var someAny: Any = 100
someAny = "어떤 타입도 수용 가능합니다"
someAny = 123.12
// Any 타입에 Double 자료를 넣어두었더라도
// Any는 Double 타입이 아니기 때문에 할당할 수 없습니다
// 명시적으로 타입을 변환해 주어야한다.
//let someDouble: Double = someAny // 컴파일 오류발생
class SomeClass {}
var someAnyObject: AnyObject = SomeClass()
// AnyObject는 클래스의 인스턴스만 수용 가능하기 때문에
// 클래스의 인스턴스가 아니면 할당할 수 없습니다
//someAnyObject = 123.12 // 컴파일 오류발생
// 다른 언어의 NULL, Null, null 등과 유사한 표현입니다.
// someAny는 Any 타입이고,
// someAnyObject는 AnyObject 타입이기 때문에
// nil을 할당할 수 없다.
//someAny = nil // 컴파일 오류발생
//someAnyObject = nil // 컴파일 오류발생
컬렉션 타입
// 빈 Int Array 생성
var integers: Array<Int> = Array<Int>()
integers.append(1) // integer배열에 1이라는 값을 추가
integers.append(100) // integer배열에 100이라는 값을 추가
//integers.append(101.1) -> Error발생 왜냐하면 데이터형이 Int 인데 소수의 값인 Double형의 값이 들어갔기때문에 형이 일치하지 않음.
print(integers) // [1, 100]
// 배열안에 특정한 값이 가지고 있는지를 확인하는 명령어 contains
print(integers.contains(100)) // true
print(integers.contains(99)) // false
integers.remove(at: 0) // 0번 index값 제거
integers.removeLast() // 마지막 index값 제거
integers.removeAll() // 배열값 전부 제거
// count : 배열안에 몇개의 값이 있는지?
print(integers.count) // 0
//integers[0] // 범위 초과 - 런타임 오류 발생
// Array를 표현하는 다양한 표현법.
// Array<Double>와 [Double]는 동일한 표현
// 빈 Double Array 생성
var doubles: Array<Double> = [Double]()
// 빈 String Array 생성
var strings: [String] = [String]()
// 빈 Character Array 생성
// []는 새로운 빈 Array
var characters: [Character] = []
// let을 사용하여 Array를 선언하면 불변 Array가 됨 (let이 불변을 값을 가지므로)
let immutableArray = [1, 2, 3]
// 불변 Array의 요소는 추가/삭제 불가 - 컴파일 오류 발생
//immutableArray.append(4)
//immutableArray.removeAll()
// Key가 String 타입이고 Value가 Any인 빈 Dictionary 생성
var anyDictionary: Dictionary<String, Any> = [String : Any]()
//Dictionary에 키와 밸류값을 추가
anyDictionary["someKey"] = "value"
anyDictionary["anotherKey"] = 100
print(anyDictionary) // ["someKey": "value", "anotherKey": 100]
// Key에 해당하는 값 변경
anyDictionary["someKey"] = "dictionary"
print(anyDictionary) // ["someKey": "dictionary", "anotherKey": 100]
// Key에 해당하는 값 제거
// 아래 두개는 거의 유사한 표현이다.
anyDictionary.removeValue(forKey: "anotherKey")
anyDictionary["someKey"] = nil
print(anyDictionary) // [:]
// 빈 Dictionary 생성
let emptyDictionary: [String: String] = [:]
// 초기 값을 가지는 Dictionary 생성
let initalizedDictionary: [String: String] = ["name": "yagom", "gender": "male"]
// let으로 선언한 불변 Dictionary는 수정 불가 - 컴파일 오류 발생
//emptyDictionary["key"] = "value"
// name 키에 해당하는 값이 Dictionary에 존재하지 않을 수 있으므로 컴파일 오류 발생한다. - 불확실성 때문에 그렇다.
// let someValue: String = initalizedDictionary["name"]
// 빈 Int Set 생성, 축약 문법이 없으므로 그냥 저대로 쓴다.
var integerSet: Set<Int> = Set<Int>()
// set안에 값을 넣을때 insert.
integerSet.insert(1)
integerSet.insert(100)
integerSet.insert(99)
integerSet.insert(99)
integerSet.insert(99)
print(integerSet) // [100, 99, 1] - 99가 중복이 안되므로 하나의 값만 출력이 된다.
// Set내 값을 확인할때도 Array와 같이 contains를 사용한다.
print(integerSet.contains(1)) // true
print(integerSet.contains(2)) // false
integerSet.remove(100)
integerSet.removeFirst()
print(integerSet.count) // 1
// Set는 집합 연산에 꽤 유용합니다
let setA: Set<Int> = [1, 2, 3, 4, 5]
let setB: Set<Int> = [3, 4, 5, 6, 7]
// 합집합 (Union)
let union: Set<Int> = setA.union(setB)
print(union) // [2, 4, 5, 6, 7, 3, 1]
// 합집합 오름차순 정렬 (Sorted)
let sortedUnion: [Int] = union.sorted()
print(sortedUnion) // [1, 2, 3, 4, 5, 6, 7]
// 교집합 (instersection)
let intersection: Set<Int> = setA.intersection(setB)
print(intersection) // [5, 3, 4]
// 차집합 (subtracting)
let subtracting: Set<Int> = setA.subtracting(setB)
print(subtracting) // [2, 1]