2021. 1. 19. 03:19ㆍSWIFT
저번 포스팅까지는 SWIFT의 패턴과 패턴 매칭에 대해 알아봤어요.
이번 포스팅에서는 조금 더 고급 문법인 where 절에 대해 알아보려고 합니다 :D
where 절은... 음 Database의 Query문을 짤 때 사용했던 기억이 있는데, 그 때도 조건을 추가할 때 사용했었던 것 같아요..🤞
SWIFT에서도 역시 where 절은 조건들을 추가할 때 사용할 수 있는 문법이랍니다.
where 절은 크게 두 가지의 용도로 사용된다고 해요..!!
첫번째로는 SWIFT의 패턴들과 결합하여 조건을 추가해줄 수 있어요.
두번째로는 타입에 대한 제약을 추가할 수 있대요. - 이 경우는 특정 프로토콜을 준수하게 하거나 하는 등의 역할을 하는 것 같아요.
그렇다면 오늘 포스팅은 이 where 절의 사용에 초점을 맞추어서 포스팅을 해볼게요 :)
값 바인딩(Value-Binding)과 where 절 사용
우선 값 바인딩(Value-Binding) 패턴과 같이 활용하는 where 절의 사용 먼저 알아보도록 할게요.
역시 예시로 같이 알아볼게요~
let tuples: [(Int, Int)] = [(1, 2), (1, -1), (1, 0), (0, 2)]
for tuple in tuples {
switch tuple {
case let (x, y) where x == y: print("x == y")
case let (x, y) where x == -y: print("x == -y")
case let (x, y) where x > y: print("x > y")
case (1, _): print("x == 1")
case (_, 2): print("y == 2")
default: print("Something else")
}
}
/*
x == 1
x == -y
x > y
y == 2
*/
위의 구문을 실행시켜보면 예시와 같은 결과를 확인할 수 있을거에요.
여기서 where 절이 어떻게 사용되는지 느낌이 오시나요?
우선 값 바인딩 패턴으로 (x, y) 튜플에 각각의 값을 할당한 것은 알 수 있는데, 왜 전부 다른 문장이 실행이 될까요..?
바로 where 절을 이용해서 각 구문의 제약을 걸고 있기 때문이에요.
where 절 이후에 들어가는 구문들이 Bool 타입을 반환하는 문장임을 알 수 있죠?
간단하게 (1, 2)로만 한 번 볼게요.
x == y라는 식이 성립하지 않죠? (넘어가)
x == -y라는 식도 성립하지 않죠? (넘어가)
x > y라는 식도 성립하지 않죠? (넘어가)
(1, _)는 와일드 카드 패턴으로 성립하죠? ("x == 1" 출력)
어렵지 않죠?
그렇다면 where 절에 Bool 타입이 들어가면 되기 때문에, &&, || 논리 연산자도 활용할 수 있겠죠?
같이 예시로 볼게요.
let tuples: [(Int, Int)] = [(1, 2), (1, -1), (1, 0), (0, 2)]
var count: Int = 0
for tuple in tuples {
switch tuple {
case let (x, y) where x == y && count > 2: print("x == y")
case let (x, y) where count < 2: print("\(x), \(y)")
default: print("Nothing")
}
count += 1
}
/*
(1, 2)
(1, -1)
Nothing
Nothing
*/
이렇게 논리 연산자를 이용해서 여러 제약 조건도 넣을 수 있겠죠?
지금까지의 방법들을 활용해서 값 바인딩(Value-Binding) 패턴과 같이 사용할 수 있어요.
옵셔널(Optional)과 where 절 사용
이번에는 옵셔널 패턴을 활용한 where 절의 사용이 어떻게 이루어지는지 알아볼게요.
let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5]
for case let number? in arrayOfOptionalInts where number > 2 {
print(number)
}
/*
3
5
*/
이번 패턴도 크게 어렵지 않죠.
이전 포스팅에서 했던 패턴에 대해 이해를 했다면 where 절의 사용이 크게 어렵지 않을 것 같아요.
표현 패턴(Expression Pattern)과 where 절 사용
이번에는 표현 패턴을 활용해서 where 절과 함께 사용하는 예시를 통해 알아볼게요.
var point: (Int, Int) = (1, 2)
switch point {
case (-2...2, -2...2) where point.0 != 0 && point.1 != 0: print("\(x), \(y)는 원점이 아닙니다")
default: print("\(point.0), \(point.1)")
}
// (1, 2)는 원점이 아닙니다
이렇듯 표현 패턴과 매칭해서 같이 사용하면 코드의 줄을 조금 더 줄여서 사용할 수 있겠죠?
지금까지는 패턴과 조합하여 조건을 추가하는 방법의 where 절 사용에 대해 알아봤어요.
이제는 타입에 대한 제약을 추가하는 where 절 사용에 대해 알아볼게요.
Generic의 타입 제약 where 절 사용
제네릭(Generic)을 사용하면 여러 타입이 일반적으로 함수나 구조체 클래스에 들어올 수 있고 통용적(?)으로 사용할 수 있었죠.
그리고 제네릭(Generic)에 플레이스 홀더라는 것 기억나시나요?
바로 이 플레이스 홀더도 타입 제약을 위해 사용을 했었는데, 역시 where 절을 사용해서도 제네릭(Generic) 타입에 타입을 제약해줄 수 있습니다.
예시로 볼게요!
// where 절을 활용한 타입 제약
func doubled<T>(integerValue: T) -> T where T: BinaryInteger {
return integerValue * 2
}
// Generic의 플레이스 홀더를 사용한 타입 제약
func doubled<T: BinaryInteger>(integerValue: T) -> T {
return integerValue * 2
}
이렇게 두 메소드를 보면 어떤 느낌이 드시나요?
둘다 T라는 타입이 BinaryInteger라는 프로토콜을 채택한 타입만 들어올 수 있다고 표현하고 있는게 눈에 들어오시나요?
결론적으로 두 메소드 동일한 표현입니다.
즉, 동일하게 작동합니다.
다음 예시도 한 번 볼게요.
// where 절을 활용한 두 가지 타입 제약
func prints<T, U>(first: T, second: U) where T: CustomStringConvertible, U: CustomStringConvertible {
print(first)
print(second)
}
// Generic을 활용한 두 가지 타입 제약
func print<T: CustomStringConvertible, U: CustomStringConvertible>(first: T, second U) {
print(first)
print(second)
}
이 경우에도 위와 다른 점은 타입 제약을 두 가지 사용했다는 점입니다.
즉, where 절은 타입을 제약할 때 Generic의 사용과 같이 할 수 있다는 것입니다.
이러한 where 절을 사용하면 조금 더 고급지게 SWIFT의 문법을 사용해서 코딩할 수 있을 것 같네요..‼️
오늘은 where 절에 대해 포스팅을 해보았습니다 :D
혹시 포스팅 내용에 틀린 점이나 궁금한 점이 있으면 말씀해주세요~
참고 레퍼런스
- SWIFT 스위프트 프로그래밍 3판 - 야곰
'SWIFT' 카테고리의 다른 글
[SWIFT] defer 후처리 (0) | 2021.02.16 |
---|---|
[SWIFT] Set (0) | 2021.01.28 |
[SWIFT] Patterns, Pattern Matching - 패턴과 패턴매칭 (2) (0) | 2021.01.16 |
[SWIFT] Patterns, Pattern Matching - 패턴과 패턴매칭 (1) (0) | 2021.01.10 |
[SWIFT] 연산자 오버로딩 + 연산자 커스텀 (0) | 2020.11.28 |