야우쓰란? "야 우리도 스위프트 할 수 있어"
in SOPT iOS
3주차의 키워드는 열거형 튜플이다.
- 튜플
튜플(tuple)이란 셀 수 있는 수량의 순서 있는 열거다. swift 에선 여러 개의 데이터를 모은 집합으로 추가와 삭제가 가능하다. 가장 큰 특징은 다른 타입을 사용해도 상관없다! 그렇다면 바로 예시를 살펴보자!
//1.
var tuple : (String, Int, Bool) = ("My age is", 20, false)
var ttuple = ("jiwon is", "beautiful", true)
//Prints
//("My age is", 20, false)
//("jiwon is", " beautiful", true)
//2.
var tuple : (String, Int, Bool) = ("My age is", 20, false)
var (text, age, fact) = tuple
print(text, age, fact)
//Prints My age is 20 false
//3.
var tuple : (String, Int, Bool) = ("My age is", 20, false)
print(tuple.0, tuple.1, tuple.2)
//Prints My age is 20 false
++ 배열과 다른 점
튜플은 변경할 수 없는 고정된 집합이지만 배열은 항목을 무기한 추가할 수 있다. 튜플은 여러 가지 타입을 저장할 수 있지만 배열은 한 가지 타입만 저장할 수 있다.
++ 타입이 너무 길때, 사용할 수 있는 꿀팁
typealias 를 사용할 수 있다.
typealias MyData = (Int, Double, String)
var tuple : MyData = (1, 1.0, "jiwon")
print(tuple)
//Prints (1, 1.0, "jiwon")
++ for 문에서 사용가능
let fruits = ["A": 10, "B": 20, "C": 30]
for (key, value) in fruits {
print(key, value)
}
fruits 안에 있는 값들을 튜플안에 담아 for 문으로 출력할 수 있다. 그렇다면 튜플 자체를 for 문으로 출력할 수는 없는 것일까? 예를 들어 아래와 같이 ,,, 근데 에러가 난다.
var tuple : (String, Int, Bool) = ("jiwon", 20, false)
for i 0...3 {
print(tuple.i)
}
++ Question
1-1. 아래 코드는 에러가 난다. 어떻게 해결해야 할까?
1-2. 만약 내가 introduction값이 필요 없다면 어떤 식으로 표현해야 할까?
let person = (name: "희재", age: 24, introduction: "저는 낭만보이입니다")
let (name, age) = person
let (name, age, introduction, gender) = person
1-1.
우선 에러 내용을 살펴보자. 3번째 줄과 4번째 줄에서 같은 에러 메세지가 발생하였다. "'(name: String, age: Int, introduction: String)' is not convertible to '(String, Int)', tuples have a different number of elements" 라는 에러로 튜플의 요소가 다르기 때문에 반환할 수 없다고 나왔다. 따라서 출력하고자 하는 바만 출력해준다면 해결해 줄 수 있다.
let person = (name: "희재", age: 24, introduction: "저는 낭만보이입니다", gender : "Man")
//let (name, age) = person
print(person.0, person.1)
//let (name, age, introduction, gender) = person
print(person.name, person.age, person.introduction, person.gender)
//Prints
//희재 24
//희재 24 저는 낭만보이입니다 Man
1-2.
사용하지 않는 튜플 요소는 언더바(_)로 대체할 수 있다. 컴파일러는 언더바로 표현된 부분을 할당하지 않고 지나간다.
let person = (name: "희재", age: 24, introduction: "저는 낭만보이입니다")
let (name, age, _) = person
print(person)
//Prints (name: "희재", age: 24, introduction: "저는 낭만보이입니다")
whildcard pattern 을 통해 언더바를 통해 무시할 수 있다는 것은 알았다. 하지만 person 을 출력해보니 introduction은 출력되지 않길 바랬던 것과 달리 처음과 동일하게 출력되었다. 그렇다면 값 자체를 바꾸는 것이 아닌 단순히 어떤 상황이 닥쳤을 때(조건문 등) 무시한다는 의미로 받아들여도 괜찮을까?
1-3.
let tuple = (171, 80)
switch tuple{
//초과 범위 연산자를 사용자 설정하려고 했는데 실패했어요 ,,,
case (172..<174, 81..<85):
print("류뚱의 비율과 비슷하시군요?")
case (174, 85):
print("류뚱의 몸매시군요?")
case (_, 85):
print("류뚱의 몸무게랑 같군요?")
case (174, _):
print("류뚱의 키와 같군요?")
default:
print("아무것도 아니시군요")
}
- Enum
enum 은 열거형으로 자동으로 열거해주는(?) 성질을 가지고 있다. 이것도 바로 예시로 보는 것이 빠를 것 같다.
enum list: Int {
case a //0
case b //1
case c //2
case d //3
case e //4
}
enum list: String {
case a //a
case b //b
case c //c
case d //d
case e //e
}
단순히 print(list.a) 를 작성한다면 case 에 선언된 element 를 불러온다. Int 로 선언된 0이란 값을 불러오고 싶다면 print(list.a.rawValue) 를 작성해야 한다. Int 는 선언된 값에서 다음 요소에 자동으로 +1 씩 선언된다. String 으로 선언된 값은 어떤 값도 지정하지 않았을 때 자동으로 case 이름과 같은 string 을 선언한다. 하지만 Character Type 은 하나하나 설정해 주어야 한다.
++ Question
2-1. design, ios, server는 어떤 값일지 유추해보세요!
enum Sopt: Int {
case plan = 0
case design
case aos = 10
case ios
case web = 30
case server
}
enum Sopt: Int {
case plan = 0
case design //1
case aos = 10
case ios //11
case web = 30
case server //31
}
2-2. Associated Value 를 이용하여 아래 내용을 코드로 구현해보세요!
++ 이걸 하기 위해서 여러가지 개념을 추가로 공부해야 함
++ Associated Value 이란?
Associated Value 이란 단어 그대로는 "연관값"을 의미한다. 따라서 연관값의 대표적인 예시인 tuple 사용하여 위의 문제를 해결할 수 있다.
import Foundation
enum Part {
case plan
case design
case android
case iOS(havemacbook : Bool)
case web
case server
}
func volunteer(part: Part, name: String){
switch part {
case .plan:
print("당신은 멋진 기획자가 될거에요!")
case .iOS(let havemacbook):
if(havemacbook) { print("맥북으로 멋지게 아요코딩하자궁!") }
else { print("잠깐만! \(part)는 맥북이 필수라는 점~!") }
case .web:
print("\(part)의 \(name) 당신은 최고의 웹 개발자입니다!")
default:
break
}
}
//Prints
volunteer(part: .plan, name: "jiwon")
volunteer(part: .design, name: "jiwon")
volunteer(part: .android, name: "jiwon")
volunteer(part: .iOS(havemacbook: true), name: "jiwon")
volunteer(part: .iOS(havemacbook: false), name: "jiwon")
volunteer(part: .web, name: "jiwon")
volunteer(part: .server, name: "jiwon")
/*
당신은 멋진 기획자가 될거에요!
맥북으로 멋지게 아요코딩하자궁!
잠깐만! iOS(havemacbook: false)는 맥북이 필수라는 점~!
web의 jiwon 당신은 최고의 웹 개발자입니다!
*/
Associated Value 와 비슷한 단어로 Associated Type 라는 것도 있다!
++ generic 이란?
타입에 의존하지 않는 타입으로 범용 코드를 작성할 때 사용 가능하다.
//before int 와 double 이기 때문에 swap 할 때 어려움!
func swapTwoInts(_ a: inout Int, _ b: inout Double) {
let temporaryA = a
a = b
b = temporaryA
}
//after
func swapTwoInts<T>(_ a: inout T, _ b: inout T) {
let temporaryA = a
a = b
b = temporaryA
}
++ Associated Type 이란?
protocol 에서 사용될 임의의 타입이름을 주는 것이다. generic 을 protocol 에 접목시킨 것이다. Protocol 은 지난 세미나 복습에서 정리해두었다. 사용법은 protocol 내부에 associated type 을 선언하고 범용타입의 이름을 선언하면 된다. 타입에 제한을 주고 싶다면 equtable 을 사용하여 가능하다. equtable 은 추후 더 공부하자!
2-3. 어떤 상황에서 Enum을 사용하면 좋을까요?
enum 과 protocol 을 많이 비교한다. 보통 enum은 사용자가 나타낼 수 있는 모든 데이터를 정의하는 경우에 사용된다. 또한 특정 값에만 조건이 필요한 경우에도 불필요하게 switch 문을 사용해야 하기 때문에 모든 값에 조건이 필요한 경우 더 유용할 것이다. 따라서 가독성을 높이고 더 직관적인 코드를 구현할 수 있다는 점이 장점이다. 반면 protocol 은 enum의 단점을 보완할 수 있다. 예를 들어, 추가로 다른 데이터를 정의할 때나 하나의 조건에만 값이 필요하다 하더라도 모든 값을 고려해주지 않고 추가로 조건문을 붙여주면 되기 때문에 더 효율적으로 사용할 수 있다.
'32YB SOPT > swift 문법 스터디' 카테고리의 다른 글
[SOPT] 야우쓰_6주차 (속성, 프로퍼티) (0) | 2023.05.31 |
---|---|
[SOPT] 야우쓰_5주차(구조체 vs 클래스, 메모리 구조) (0) | 2023.05.24 |
[SOPT] 야우쓰_4주차 (컬렉션 타입, array, dictionary, set, 값타입, 참조타입) (0) | 2023.05.17 |
[SOPT] 야우쓰_2주차 (옵셔널 삼항연산자) (0) | 2023.04.30 |
[SOPT] 야우쓰_1주차 (swift 타입 / 기본 연산자 / 조건문 / 반복문 ) (0) | 2023.04.26 |