[Swift 문법] - Array, Set, Tuple, Dictionary, Enumeration

sun02·2021년 7월 7일
0

100 days of Swift 

목록 보기
1/40

1. 배열

배열은 한 개의 값에 저장되어 있는 값들의 모임이다.

예를 들어, 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]
  • 배열은 0부터 세어지므로 만약 네가 “Paul McCartney”를 읽고 싶다면 다음과 같이 적으면 된다

만약 type annotations를 쓸 것이라면, 배열은 괄호안에 적혀진다 : [String], [Int], [Double], [Bool]

Swift는 왜 array를 가질까?

스위프트의 문자열, 정수, Booleans, 실수들은 일시적으로 단일 값을 저장할 수 있지만 만약 많은 값을 저장하고 싶다면 arrays를 사용할 것이다.

다른 데이터 타입들처럼 상수와 변수 array를 만들 수도 있지만
차이점은 array는 그 안에 많은 값들을 가질 수 있다는 것이다.

스위프트에서 배열은 원하는 만큼 커질 수도 작아질 수도 있다.

만약 그들이 변수라면, 데이터를 자유롭게 추가하거나 삭제 또는 재정렬할 수도 있다.

0부터 시작되는 위치를 사용하여 배열의 값을 읽는다.

이러한 “0부터 계산” 을 기술하는 단어가 있다
: Swift의 배열은 zero-based.라고 한다.
만약 네가 유효하지 않은 인덱스를 사용하여 배열을 읽으려고 한다면 스위프트는 자동으로 너의 프로그램을 충돌시킬 것이다.

2. 집합

집합은 배열과 같이 값들의 모임이지만 두 가지 차이점을 가진다

  • 항목들은 순서대로 저장되지 않는다 : 그들은 무작위로 저장된다
  • 어떠한 항목도 집합 내에서 두 번 나타나지 않는다: 모든 항목들은 고유하다
let colors = Set([“red”, “green”, “blue”])
  • 다음과 같이 집합을 배열처럼 바로 만들 수 있다

집합 colors의 값을 playground에서 보면
그 순서가 내가 만든 순서와 같지 않다는 것을 알 수 있을 것이다.
이것은 무작위는 아니고, 그냥 순서가 없는 것이다 – 스위프트는 이 순서에 대해 보장하지 않는다. 순서가 없기 때문에, 집합에서는 배열에서처럼 숫자 위치를 사용해서 값을 읽을 수 없다.

let colors2 = Set([“red”, “green”, “blue”, “red”, “blue”])
  • 다음과 같이 집합에 중복 항목을 넣으려고 한다면, 그 중복 값은 무시될 것이다.

최종 colors2 집합도 여전히 red, green, blue 만 포함할 것이다.

Set은 Swift의 array와 어떻게 다를까?

Set과 array 둘 다 스위프트에서 중요하고 이 둘의 차이점을 아는 것은 주어진 상황에서 어떤 선택을 해야하는지 도와줄 수 있을 것이다.

집합과 배열 둘 다 한 변수 안에 다수의 값을 포함하고 있는 데이터의 모음이다. 그러나, 그들이 값을 어떻게 가지고 있는지가 중요하다
: 집합은 순서가 없고 중복을 포함할 수 없는 반면 배열은 순서를 가지고 중복을 포함할 수 있다.

이러한 두 차이점은 작아보이지만, 흥미로운 부작용을 갖고 있다
: 집합은 개체들을 네가 추가한 순서대로 저장할 필요가 없기 때문에 빠르게 얻는 것에 최적화되어 있는 모습으로 저장할 수 있다.
따라서 네가 “이 집합이 항목 X를 포함하고 있나”라고 한다면, 그 집합이 얼마나 크던지 상관없이 너는 바로 대답을 얻을 수 있을 것이다.

이와 비교하여, 배열은 그들의 항목들을 네가 준 순서에 맞게 저장하기 때문에 10000개의 항목을가지는 배열이 항목 X를 포함하고 있는지 확인하기 위해 스위프트는 맨 처음 아이템부터 시작학여 그것이 발생될 때까지 모든 아이템 하나하나를 체크해야한다.

이러한 차이는 “이 항목이 존재하는가?” 와 같은 질문을 할 때 집합이 더 유용하다는 것을 의미한다.

3. Tuples

튜플은 한 값 안에 여러 값들을 함께 저장할 수 있게 한다.
배열과 비슷하게 들리겠지만, 다음과 같은 차이점들을 가진다.

  • 튜플의 항목은 추가하거나 제거될 수 없다: 튜플의 크기는 고정되어있다.
  • 튜플의 항목의 타입은 변화할 수 없다: 튜플은 항상 만들어졌을 때와 같은 타입을 가진다.
  • 튜플의 항목에 숫자 위치나 이름으로 접근할 수 있지만, 존재하지 않는 숫자나 이름으로는 읽을 수 없다.
var name = (first: “Taylor”, last: “Swift”)
  • 튜플은 다음과 같이 여러 항목들을 괄호 안에 배치하며 생긴다
name.0
  • 숫자를 이용하여 항목에 접근할 수 있다.
name.first
  • 또는 이름을 사용해서 접근할 수 있다.

생성한 후에 튜플안의 값은 바꿀 수 있지만 값의 타입은 바꿀 수 없다.
따라서 만약 name을 (first: “Justin”, age: 25)로 바꾸려 한다면 에러를 얻을 것이다

Tuples는 Swift의 arrays와 어떻게 다를까?

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)
  • 다음과 같이 문자열, 정수, boolean 타입을 단일 값으로 결합한 튜플을 만들 수 있다. 배열에서는 매우 보기 흉할 것이다.

4. 배열 vs 집합 vs 튜플

배열, 집합, 튜플 들은 첫 눈에는 비슷해 보이지만 그들은 용도가 다르다.
어떤 것을 사용해야하는지 알기 위해 몇 가지 규칙이 있다.

구체적이고 고정된 각각의 항목들이 정확한 위치나 이름을 가진 모임이 필요하다면

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을 사용해야 할까?

  • 배열순서를 지키고 중복 값을 가질 수 있지만,
  • 집합순서가 없고 중복을 가질 수 없다,
  • 그리고 튜플은 그 안에 고정된 타입과 고정된 값을 가진다.

5. Dictionaries

딕셔너리는 배열처럼 값들의 모음이지만
정수 위치로 항목을 저장하기보다 네가 원하는 것을 사용하여 접근할 수 있다.

딕셔너리 데이터를 저장하는 가장 일반적인 방법은 문자열을 사용하는 것이다.

let heights = [
“Taylor Swift” : 1.78,
“Ed Sheeran” : 1.74
]
  • 다음과 같이 가수의 이름을 사용하여 그들의 키를 저장하는 딕셔너리를 만들 수 있다.

배열과 같이 딕셔너리는 괄호로 시작하고 끝나며 각각의 항목들은 콤마로 분리된다.
그러나 저장하려는 값과 저장하려는 식별자 사이에는 콜론을 사용하여 구분한다.

heights[“Taylor Swift”]
  • 다음과 같이 딕셔너리에서 데이터를 읽어오기 위해 'keys'라고 불리는 식별자를 사용할 수 있다.

참고 : type annotations를 사용할 땐, 딕셔너리들은 괄호로 적혀지고 식별자와 값의 타입사이에는 콜론이 사용된다. 예를 들어, [String: Double][String: String] 과 같이.

Swift는 왜 배열뿐만 아니라 dictionaries도 가질까?

Dictionaries와 array 둘 다 하나의 변수에 많은 데이터를 저장하는 방법이지만, 그들의 저장 방식은 다르다

  • 딕셔너리는 우리가 추가하고 싶은 항목을 명시하는 “Key”를 고를 수 있게 하는 반면
  • 배열은 항목을 그저 순차적으로 추가하게 한다.

집합처럼 딕셔너리는 항목들을 특정한 순서에 맞게 저장하지 않으므로 그들은 빠른 검색을 위해 최적화된 방식으로 항목들을 저장한다.
따라서, 우리가 user[“country”]라고 했을 때 딕셔너리는 항목을 10000개 정도 갖고 있더라도 그 key의 항목을 즉시 보여줄 것이다,

튜플과 다르게, 딕셔너리의 key가 존재한다는 것을 보장할 수는 없다.
따라서 딕셔너리의 값을 읽을 때 아무것도 받지 못할 수도 있다 – 너가 존재하지 않는 key를 요구했을 것이다!

6. 딕셔너리 default 값

존재하지 않는 key를 사용해서 딕셔너리의 값을 읽으려 한다면, 스위프트는 nil을 반환할 것이다.
이것이 네가 원하는 것일 수도 있지만, 대안이 있다 : 우리는 없는 key를 요청할 때 사용할 default 값을 제공할 수 있다.

let favoriteIceCream = [
“Paul” : “Chocolate”,
“Sophie”: “Vanilla”
]
  • 다음과 같이 두 사람을 위한 favorite ice cream 딕셔너리를 만들어 보자
favoriteIceCream[“Paul”]
  • paul의 favoriteIceCream을 다음과 같이 읽을 수 있다.
favoriteIceCream[“Charlotte”]
  • 만약 다음과 같이 Charlotte의 favoriteIceCream을 읽으려고 한다면, nil을 반환받을 것이고, 이것은 Swift가 해당 키에 맞는 값을 가지고 있지 않다는 것을 의미한다.
favoriteIceCream[“Charlotte”, default: “Unknown”]
  • nil을 반환받지 않도록 다음과 같이 디폴트 값 "UnKnow"을 제공한다.

Swift는 왜 딕셔너리에 default값을 가지는 가?

딕셔너리에서 값을 읽어올 때 값을 받을 수도 있고 nil값을 받을 수도 있다 – 해당 key에 값이 없을 수도 있기 때문이다.
이 때, 값이 없다는 것은 코드에서 문제를 발생시킬 수 있다. 없어진 값들은 안전하게 다루기 위한 추가 기능을 추가해야하기 때문이다.

그렇기에 요청한 key가 존재하지 않을 때 사용할 백업 값(default값)을 제공한다.

let results = [“English”:100,”French”:85,”geography”:75]
  • 다음과 같이 학생의 시험 결과를 저장하는 딕셔너리가 있다.

영어 100, 프랑스어 85, 지리학 75점으로 세팅하였다.
만약 역사 점수를 읽고 싶다면, 우리가 원하는 것에 따라 어떻게 해야하는 지는 달라진다.

  • 만약 빈 값이 그 학생이 시험에서 낙제한 것을 의미한다면, 우리는 디폴트 값을 0으로 설정하여 우리가 항상 정수를 받을 수 있게 한다.
  • 만약 빈 값이 그 학생이 아직 시험을 치지 않은 것을 의미한다면, 우리는 디폴트 값을 건너뛰고 nil값을 찾아야한다.
let historyResult = results[“history”,default:0]
  • 딕셔너리를 사용할 때 항상 디폴트 값을 필요로 하는 것은 아니지만 사용하는 법은 매우 쉽다

7. 빈 collection 만들기

배열, 집합, 딕셔너리들은 한 장소에 여러 값들을 모으기 때문에 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”]
  • Swift를 공부할 때, 다음과 같은 배열은 일반적이다.

여섯 개의 문자열을 가지는 상수 배열이고
상수이기 때문에 우리는 이 배열에 더 추가할수 없다. – 우리는 배열이 만들어질 때 모든 항목을 알고, 우리 프로그램은 저 고정된 데이터만 사용할 수 있다.

하지만 때떄로 모든 데이터를 미리 알지 못하는 경우
빈 컬렉션을 만들고 데이터를 계산할 때 추가하면 된다.

예를 들어, 우리는 고정된 names배열이 있다.
만약 우리가 J로 시작하는 이름을 알고 싶다면 우리는

1) JNames 로 불리는 빈 문자열 배열을 만든다
2) Names 배열에서 “J”로 시작되는지 모든 이름을 체크한다
3) 만약 그렇다면, 그것을 jNames 배열에 추가한다

모든 이름들을 다루고 나면,
JNames배열에 두 개의 문자열을 갖게 된다 : jianyu 와 janet.

8. Enumerations(열거형)

Enumerations – 보통 enums 라고 불림 – 은 관련된 값들을 사용하기 쉬운 방식으로 정의하는 방법이다.

let result = “Failure”
  • 어떤 작업의 성공이나 실패를 나타내는 코드를 적고 싶다면, 다음과 같이 문자열로 나타낼 수 있을 것이다.
let result2 = “failed”
let result3 = “fail”
  • 하지만 만약 누군가가 실수로 다른 이름을 사용하게 된다면 어떻게 될까?
    • 위 세가지는 모두 다른 문자열이기에 모두 다른 것을 의미하게 된다.
enum result {
      case success
      case failure
}
  • 열거형으로 우리는 success 또는 failureresult의 타입을 정의할 수 있다.
let result4 = result.failure
  • 다음과 같이 둘 중에 하나의 값을 선택할 수 있다.

이와 같이 열거형은 실수로 다른 문자열을 사용하는 것을 막아준다.

Swift는 왜 enums를 필요로할까?

Enums는 Swift의 매우 강력한 특징이며 이것은 매우 많은 방법으로 다양한 장소에서 사용된다.
그러나 많은 언어들에는 열거형이 없지만 그들은 잘 작동하므로 Swift는 왜 열거형을 필요로하지 궁금할 것이다

Enum은 단순히 값에 대한 좋은 이름이다.
Direction이라는 이름의 north, south, east, west의 케이스를 가지는 열거형을 만들 수 있다.
물론 케이스를 1,2,3,4인 정수로도 만들 수 있지만 3이 무엇을 의미하는지 기억할 수 있을까? 또는 만약 실수로 5를 입력한다면?

따라서, 열거형은 구체적이고 안전하게 Direction.north라고 말할 수 있는 방법이다.
만약 우리가 Direction.thatWay라고 작성하고 이러한 케이스가 존재하지 않는다면, Swift는 코드를 거절할 것이다 – 해당 열거형 케이스를 이해하지 못한다.

Swift는 열거형 값을 매우 간단하게 저장할 수 있기에 문자열보다 만들고 저장할 때 훨씬 빠르다

9. Enum associated vaules

간단한 값을 저장할 뿐만 아니라 열거형은 각 케이스에 연결된 관련 값을 저장할 수도 있다. 이것이 열거형에 추가 정보를 첨부하여 더 미묘한 데이터를 나타낼 수 있게 한다.

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”)
  • 이제 우리는 더 정확히 축구얘기를 한다고 말할 수 있다.

10. Enum raw values

때때로 열거형에 값을 할당할 수도 있어야 한다.
이것은 열거형을 동적으로 생성하고 다양한 방식으로 사용할 수 있게 한다.

enum Planet : Int {
     case mercury
     case venus
     case earth
     case mars
}
  • 다음과 같이 각각의 케이스 마다 정수 값을 할당하는 Planet 열거형을 만들 수 있다.

스위프트는 자동으로 0부터 숫자를 할당할 것이고 그 숫자를 사용하여 적절한 열거형 케이스의 인스턴스를 만들 것이다.

let earth = Planet(rawValue: 2)
  • earth 는 숫자 2를 받을 것이고 너는 다음과 같이 적을 수 있다.

하나 이상의 케이스에 구체적인 값을 할당하고 스위프트가 나머지를 생성하도록 할 수도 있다.

enum Planet : Int {
     case mercury = 1
     case venus
     case earth
     case mars
}
  • 지구를 두 번째 행성으로 여기는 것은 우리에게 자연스럽지 않기 때문에 다음과 같이 적을 수 있다.

이제 스위프트는 mecury에 1을 할당하고 거기서 위로 세어 지구는 세 번째 행성이 된다.

출처

0개의 댓글