본문 바로가기

학습 노트/Swift (2021)

067 ~ 070. Tuples (튜플)

Tuples

Syntax

(expr1, expr2, ...)
let i = 12, 34

 

결과

//error

int는 스칼렛 타입이기 때문에 여러개의 값을 저장 할 수 없다.
int를 제외한 다른 대부분의 타입도 스칼렛 타입이므로 하나의 값을 저장 할 수 있다.

let i - (13, 34)
print(i)

 

결과

(12, 34)

괄호를 사용하면 이 때무터 튜플을 사용하며, 두 개 이상의 값을 저장 할 수 있다.
튜플은 컴파운드 타입이다.

let data = ("<html>", 200, "OK", 12.34)
print(type(of: data))
결과

(String, Int, String, Double)

튜플 안에 저장 된 멤버에 따라 여러 자료형을 저장 할 수 있다.
튜플 안의 멤버의 수와 자료형은 튜플이 생성됨과 동시에 결정되며, 이후 변경이 불가능하다.
하지만 멤버의 내용을 바꾸는 것은 가능하다.

튜플에 저장된 값에 접근하기

Syntax

tuple.n
let data = ("<html>", 200, "OK", 12.34)
print(data.0)
print(data.1)
print(data.2)
print(data.3)
결과

<html>
200
OK
12.34

200 OK 12.34 문법의 'n'은 index로 0부터 시작함에 유의하자.

튜플의 값 변경하기

var data = ("<html>", 200, "OK", 12.34)
data.1 = 300
print(data.1)
결과

300

기본 자료형들과 똑같이 var로 선언하면 멤버에 접근하여 값을 변경할 수 있다.
이를 mutable/mutability라고 하고 가변성이라고 말 한다.

 

Named Tuples

위에서 생선한 튜플은 unnamed tuple로 이름이 없는 튜플이다.
index를 사용해서 멤버에 접근이 가능하지만, index만으론 정확히 무엇을 의미하는 멤버인지 판단이 불가능하다.
따라서 멤버에 이름을 붙여줄 수 있는데, 이를 named tuple이라고 부른다.

Syntax

(name1: expr1, name2: expr2, ...)

tuple.memberName
 
let named = (body: "<html>", statusCode: 200, statusMsg: "OK", data: 12.34)

print(named.1)
print(named.body)

 

결과

<html>
<html>

index 접근과 member name 접근 둘 다 사용 가능하다.

named tuple을 사용하는 경우 코드의 가독성이 높아진다는 장점이 있다.

 

Tuple Decomposition (튜플 분해)

Syntax

let (name1, name2, ...) = tupleExpr
var (name1, name2, ...) = tupleExpr
 
let data = ("<html>", 200, "OK", 12.34)

let body = data.0
let code = data.1
let message = data.2
let size = data.3

print(body)
print(code)
print(message)
print(size)

 

결과

"<html>"
200
"OK"
12.34
 
let data = ("<html>", 200, "OK", 12.34)

let (body, code, messgae, size) = data

print(body)
print(code)
print(message)
print(size)

 

결과

"<html>"
200
"OK"
12.34

위의 코드와 아래의 코드는 완전히 동일한 코드이지만,훨씬 간결하다는 데에 장점이 있다.
다만 튜플 분해를 사용할 때 이름의 수와 튜플의 멤버의 수가 일치해야 사용 가능하다.

 

Tuple Matching

let resolution = (3840.0, 2160.0)

if resolution.0 == 3840 && resolution.1 == 2160 {
	print("4K")
}

 

결과

4K

이 경우 정상 구동 되지만, 조건이 추가되는 경우 else if 문을 추가해야 한다는 점과,
조건이 길어져 난해하다는 단점이 있다.

 
let resolution = (3840.0, 2160.0)

switch resolution {
case(3840, 2160):
	print("4K")
default:
	break
}

 

결과

4K

코드가 훨씬 단순해 지며, case를 추가하는 것으로 조건을 쉽게 추가 할 수 있다.
value binding이나 wildcard를 사용한다면 더 다양한 조건에 대응할 수도 있다.

let resolution = (4000.0, 2160.0)

switch resolution {
case(3840...4096, 2160):
	print("4K")
default:
	break
}

 

결과

4K

인터벌 매칭을 사용 할 수 있다.

 
let resolution = (4000.0, 1080.0)

switch resolution {
case(_, 1080):
	print("FHD")
case(3840...4096, 2160):
	print("4K")
default:
	break
}

 

결과

FHD

wildcard를 사용할 수도 있다.

let resolution = (1920.0, 1080.0)

switch resolution {
case let(w, h) where w / h == 16.0 / 9.0:
	print("16:9")
case(_, 1080):
	print("FHD")
case(3840...4096, 2160):
	print("4K")
default:
	break
}

 

결과

16:9

value binding도 사용 할 수 있다.


Log

2021.08.19.
블로그 이전으로 인한 글 옮김 및 수정