예를 들어, John, Paul, George, Ringo는 이름이지만 배열은 이것들을 Beatles라는 이름의 단일 값 안에 그룹화할 수 있게 한다.
let john = “John Lennon”
let paul = “Paul McCartney”
let George = “George Harrison”
let ringo = “Ringo Starr”
let beatles = [john, paul, George, ringo]
마지막 줄이 배열이다
: 괄호로 시작해서 괄호로 끝나며 배열 안의 각 항목들은 콤마로 분리된다.
beatles[1]
만약 type annotations를 쓸 것이라면, 배열은 괄호안에 적혀진다 : [String], [Int], [Double], [Bool]
스위프트의 문자열, 정수, Booleans, 실수들은 일시적으로 단일 값을 저장할 수 있지만 만약 많은 값을 저장하고 싶다면 arrays를 사용할 것이다.
다른 데이터 타입들처럼 상수와 변수 array를 만들 수도 있지만
차이점은 array는 그 안에 많은 값들을 가질 수 있다는 것이다.
만약 그들이 변수라면, 데이터를 자유롭게 추가하거나 삭제 또는 재정렬할 수도 있다.
이러한 “0부터 계산” 을 기술하는 단어가 있다
: Swift의 배열은 zero-based.라고 한다.
만약 네가 유효하지 않은 인덱스를 사용하여 배열을 읽으려고 한다면 스위프트는 자동으로 너의 프로그램을 충돌시킬 것이다.
집합은 배열과 같이 값들의 모임이지만 두 가지 차이점을 가진다
let colors = Set([“red”, “green”, “blue”])
집합 colors의 값을 playground에서 보면
그 순서가 내가 만든 순서와 같지 않다는 것을 알 수 있을 것이다.
이것은 무작위는 아니고, 그냥 순서가 없는 것이다 – 스위프트는 이 순서에 대해 보장하지 않는다. 순서가 없기 때문에, 집합에서는 배열에서처럼 숫자 위치를 사용해서 값을 읽을 수 없다.
let colors2 = Set([“red”, “green”, “blue”, “red”, “blue”])
최종 colors2 집합도 여전히 red, green, blue 만 포함할 것이다.
Set과 array 둘 다 스위프트에서 중요하고 이 둘의 차이점을 아는 것은 주어진 상황에서 어떤 선택을 해야하는지 도와줄 수 있을 것이다.
집합과 배열 둘 다 한 변수 안에 다수의 값을 포함하고 있는 데이터의 모음이다. 그러나, 그들이 값을 어떻게 가지고 있는지가 중요하다
: 집합은 순서가 없고 중복을 포함할 수 없는 반면 배열은 순서를 가지고 중복을 포함할 수 있다.
이러한 두 차이점은 작아보이지만, 흥미로운 부작용을 갖고 있다
: 집합은 개체들을 네가 추가한 순서대로 저장할 필요가 없기 때문에 빠르게 얻는 것에 최적화되어 있는 모습으로 저장할 수 있다.
따라서 네가 “이 집합이 항목 X를 포함하고 있나”라고 한다면, 그 집합이 얼마나 크던지 상관없이 너는 바로 대답을 얻을 수 있을 것이다.
이와 비교하여, 배열은 그들의 항목들을 네가 준 순서에 맞게 저장하기 때문에 10000개의 항목을가지는 배열이 항목 X를 포함하고 있는지 확인하기 위해 스위프트는 맨 처음 아이템부터 시작학여 그것이 발생될 때까지 모든 아이템 하나하나를 체크해야한다.
이러한 차이는 “이 항목이 존재하는가?” 와 같은 질문을 할 때 집합이 더 유용하다는 것을 의미한다.
튜플은 한 값 안에 여러 값들을 함께 저장할 수 있게 한다.
배열과 비슷하게 들리겠지만, 다음과 같은 차이점들을 가진다.
var name = (first: “Taylor”, last: “Swift”)
name.0
name.first
생성한 후에 튜플안의 값은 바꿀 수 있지만 값의 타입은 바꿀 수 없다.
따라서 만약 name을 (first: “Justin”, age: 25)로 바꾸려 한다면 에러를 얻을 것이다
Swift를 공부할 때, tuples와 arrays는 같아보일 수 있지만 실제로는 매우 다를 수밖에 없다
튜플과 배열은 한 변수 안에 여러 값을 가질 수 있지만 튜플은 변화될 수 없는 고정 집합을 가지는 반면 변수 배열은 항목을 무기한으로 추가할 수 있다.
var website = (name: “Apple”,url:”www.apple.com”)
만약 우리가 그 사이트를 마지막으로 방문한 날짜를 저장하고 싶더라도, 우리는 할 수 없다. - 이것은 두 문자열 항목 name, url만 가지고 더 이상은 없기 때문이다.
이 항목들은 구체적이고 이름이 지정되어있기 때문에 website.name , website.url과 같이 읽을 수 있다.
var website = [“Apple”,”www.apple.com”]
배열의 항목은 이름이 없기 때문에, 숫자를 이용하여 값을 읽어야한다. - website[0], website[1]
변수 배열이기 때문에 항목을 추가할 수도 있다.
배열은 우리가 지정한 두 개가 아닌 여러 문자열을 저장할 수 있다.
각각의 값이 구체적으로 사용자에 의해 만들어질 수 있고
이름을 지정할 뿐만아니라 타입도 지정할 수 있다.
var person = (name: “Paul”, age:40, isMarried: true)
배열, 집합, 튜플 들은 첫 눈에는 비슷해 보이지만 그들은 용도가 다르다.
어떤 것을 사용해야하는지 알기 위해 몇 가지 규칙이 있다.
구체적이고 고정된 각각의 항목들이 정확한 위치나 이름을 가진 모임이 필요하다면
let address = (house: 555, street: “Taylor Swift Avenue”, city: “Nashville”)
고유한 값의 모음이 필요하거나 특정 항목이 포함되어있는지 매우 빠르게 알아야할 필요가 있다면
let set = Set([“aardvark”, “astronaut”, “azalea”])
중복을 포함할 수 있거나 항목의 순서가 중요한 값들의 모음이 필요하다면
let pythons = [“Eric”, “Graham”, “John”, “Michael”, “Terry”, “Terry”]
위 세 타입중에 배열이 가장 일반적으로 많이 사용된다.
Swift 에서 언제 array, set, tuple을 사용해야 할까?
딕셔너리는 배열처럼 값들의 모음이지만
정수 위치로 항목을 저장하기보다 네가 원하는 것을 사용하여 접근할 수 있다.
딕셔너리 데이터를 저장하는 가장 일반적인 방법은 문자열을 사용하는 것이다.
let heights = [
“Taylor Swift” : 1.78,
“Ed Sheeran” : 1.74
]
배열과 같이 딕셔너리는 괄호로 시작하고 끝나며 각각의 항목들은 콤마로 분리된다.
그러나 저장하려는 값과 저장하려는 식별자 사이에는 콜론을 사용하여 구분한다.
heights[“Taylor Swift”]
참고 : type annotations를 사용할 땐, 딕셔너리들은 괄호로 적혀지고 식별자와 값의 타입사이에는 콜론이 사용된다. 예를 들어, [String: Double][String: String] 과 같이.
Dictionaries와 array 둘 다 하나의 변수에 많은 데이터를 저장하는 방법이지만, 그들의 저장 방식은 다르다
집합처럼 딕셔너리는 항목들을 특정한 순서에 맞게 저장하지 않으므로 그들은 빠른 검색을 위해 최적화된 방식으로 항목들을 저장한다.
따라서, 우리가 user[“country”]라고 했을 때 딕셔너리는 항목을 10000개 정도 갖고 있더라도 그 key의 항목을 즉시 보여줄 것이다,
튜플과 다르게, 딕셔너리의 key가 존재한다는 것을 보장할 수는 없다.
따라서 딕셔너리의 값을 읽을 때 아무것도 받지 못할 수도 있다 – 너가 존재하지 않는 key를 요구했을 것이다!
존재하지 않는 key를 사용해서 딕셔너리의 값을 읽으려 한다면, 스위프트는 nil을 반환할 것이다.
이것이 네가 원하는 것일 수도 있지만, 대안이 있다 : 우리는 없는 key를 요청할 때 사용할 default 값을 제공할 수 있다.
let favoriteIceCream = [
“Paul” : “Chocolate”,
“Sophie”: “Vanilla”
]
favoriteIceCream[“Paul”]
favoriteIceCream[“Charlotte”]
favoriteIceCream[“Charlotte”, default: “Unknown”]
딕셔너리에서 값을 읽어올 때 값을 받을 수도 있고 nil값을 받을 수도 있다 – 해당 key에 값이 없을 수도 있기 때문이다.
이 때, 값이 없다는 것은 코드에서 문제를 발생시킬 수 있다. 없어진 값들은 안전하게 다루기 위한 추가 기능을 추가해야하기 때문이다.
그렇기에 요청한 key가 존재하지 않을 때 사용할 백업 값(default값)을 제공한다.
let results = [“English”:100,”French”:85,”geography”:75]
영어 100, 프랑스어 85, 지리학 75점으로 세팅하였다.
만약 역사 점수를 읽고 싶다면, 우리가 원하는 것에 따라 어떻게 해야하는 지는 달라진다.
let historyResult = results[“history”,default:0]
배열, 집합, 딕셔너리들은 한 장소에 여러 값들을 모으기 때문에 collection 이라 불린다
만약 빈 콜렉션을 만들고 싶다면 그냥 괄호 안에 타입을 적으면 된다.
var teams = [String: String]()
teams[“Paul”] = “Red”
var results = [Int]()
var words = Set<String>()
var numbers = Set<Int>()
왜냐하면 Swift는 딕셔너리와 배열에만 특별한 규칙을 갖고있기 때문이다.
다른 타입들은 집합 처럼 꺾쇠 괄호를 사용해야만 한다.
var scores = Dictionary<String, Int>()
var results = Array<Int>()
let names = [“Eleanor”, “Chidi”, “Tahani”, “Jianyu”, “Michael’, “Janet”]
여섯 개의 문자열을 가지는 상수 배열이고
상수이기 때문에 우리는 이 배열에 더 추가할수 없다. – 우리는 배열이 만들어질 때 모든 항목을 알고, 우리 프로그램은 저 고정된 데이터만 사용할 수 있다.
하지만 때떄로 모든 데이터를 미리 알지 못하는 경우
빈 컬렉션을 만들고 데이터를 계산할 때 추가하면 된다.
예를 들어, 우리는 고정된 names배열이 있다.
만약 우리가 J로 시작하는 이름을 알고 싶다면 우리는
1) JNames 로 불리는 빈 문자열 배열을 만든다
2) Names 배열에서 “J”로 시작되는지 모든 이름을 체크한다
3) 만약 그렇다면, 그것을 jNames 배열에 추가한다
모든 이름들을 다루고 나면,
JNames배열에 두 개의 문자열을 갖게 된다 : jianyu 와 janet.
Enumerations – 보통 enums 라고 불림 – 은 관련된 값들을 사용하기 쉬운 방식으로 정의하는 방법이다.
let result = “Failure”
let result2 = “failed”
let result3 = “fail”
enum result {
case success
case failure
}
let result4 = result.failure
이와 같이 열거형은 실수로 다른 문자열을 사용하는 것을 막아준다.
Enums는 Swift의 매우 강력한 특징이며 이것은 매우 많은 방법으로 다양한 장소에서 사용된다.
그러나 많은 언어들에는 열거형이 없지만 그들은 잘 작동하므로 Swift는 왜 열거형을 필요로하지 궁금할 것이다
Enum은 단순히 값에 대한 좋은 이름이다.
Direction이라는 이름의 north, south, east, west의 케이스를 가지는 열거형을 만들 수 있다.
물론 케이스를 1,2,3,4인 정수로도 만들 수 있지만 3이 무엇을 의미하는지 기억할 수 있을까? 또는 만약 실수로 5를 입력한다면?
따라서, 열거형은 구체적이고 안전하게 Direction.north라고 말할 수 있는 방법이다.
만약 우리가 Direction.thatWay라고 작성하고 이러한 케이스가 존재하지 않는다면, Swift는 코드를 거절할 것이다 – 해당 열거형 케이스를 이해하지 못한다.
Swift는 열거형 값을 매우 간단하게 저장할 수 있기에 문자열보다 만들고 저장할 때 훨씬 빠르다
간단한 값을 저장할 뿐만 아니라 열거형은 각 케이스에 연결된 관련 값을 저장할 수도 있다. 이것이 열거형에 추가 정보를 첨부하여 더 미묘한 데이터를 나타낼 수 있게 한다.
enum activity {
case bored
case running
case talking
case singing
}
이 열거형은 누군가 talking하고 있다고 알려줄 수 있지만, 무엇에 대해 대화하는지는 알 수 없다.
또한 우리는 누군가 running하고 있는 것을 알 수 있지만 그들이 어디서 런닝을 하는지는 알 수 없다.
enum activity {
case bored
case running(destination: String)
case talking(topic: String)
case singing(volume: Int)
}
let talking = Activity.talking(topic: “football”)
때때로 열거형에 값을 할당할 수도 있어야 한다.
이것은 열거형을 동적으로 생성하고 다양한 방식으로 사용할 수 있게 한다.
enum Planet : Int {
case mercury
case venus
case earth
case mars
}
스위프트는 자동으로 0부터 숫자를 할당할 것이고 그 숫자를 사용하여 적절한 열거형 케이스의 인스턴스를 만들 것이다.
let earth = Planet(rawValue: 2)
하나 이상의 케이스에 구체적인 값을 할당하고 스위프트가 나머지를 생성하도록 할 수도 있다.
enum Planet : Int {
case mercury = 1
case venus
case earth
case mars
}
이제 스위프트는 mecury에 1을 할당하고 거기서 위로 세어 지구는 세 번째 행성이 된다.