티스토리 뷰
[시작]
- 특정 패턴과 결합하여 조건을 추가하는 역할
[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, let y) where x > y:
print("x > y")
case (1, _):
print("x = 1")
case (_, 2):
print("y = 2")
default:
print("default")
}
}
let firstValue: Int = 50
let secondValue: Int = 30
switch firstValue + secondValue {
case let total where total > 100:
print("total > 100")
case let total where total < 0:
print("total < 0")
case let total where total == 0:
print("zero")
case let total:
print(total)
}
//80
값 바인딩 패턴과 함께 where절이 사용된 예
let array: [Int?] = [nil, 2, 6, nil, nil]
for case let value? in array where value > 3 {
print(value)
}
//6
let any: Any = "ABC"
switch any {
case let value where value is String:
print("It is String")
case let value where value is Int:
print("It is Integer")
case let value where value is Double:
print("It is Real")
default:
print("Unknown")
}
var things: [Any] = [Any]()
things.append(0)
things.append(0.0)
things.append(42)
things.append(3.141592)
things.append("HELLO")
things.append((3.0, 5.0))
things.append { (name: String) -> String in
return "Hello \(name)"
}
for thing in things {
switch thing {
case 0 as Int:
print("zero as an Int")
case 0 as Double:
print("zero as an Double")
case let someInt as Int:
//case let someInt where someInt is Int
print(someInt)
case let someDouble as Double:
//case let someDouble where someDouble is Double
print(someDouble)
case is Double:
print("Double")
case let someString as String:
//case let someString where someString is String
print(someString)
case let (x, y) as (Double, Double):
//case let (x, y) where (x, y) is (Double, Double)
print((x, y))
case let stringConvereter as (String) -> String:
//case let stringConvereter where stringConverter is (String) -> String
print(stringConvereter("asdasf"))
default:
print("default")
}
}
var point: (Int, Int) = (1, 2)
switch point {
case (let x, let y) where (x, y) == (1, 2):
//case let (x, y) where (x, y) == (1, 2):
//case (1, 2):
print(x, y)
case (-2...2, -2...2) where point.0 != 1:
print("adsdsf")
default:
break
}
표현 패턴과 함께 where절이 사용된 예
- 프로토콜 익스텐션에 where절을 사용하여 이 익스텐션이 특정 프로토콜을 준수하는 타입에만 적용될 수 있도록 제약을 줄 수 있다.
protocol SelfPrintable {
func printSelf()
}
struct Person: SelfPrintable {}
extension Int: SelfPrintable {}
extension UInt: SelfPrintable {}
extension Double: SelfPrintable {}
extension String: SelfPrintable {}
//익스텐션 초기구현
extension SelfPrintable where Self: BinaryInteger, Self: Comparable {
func printSelf() {
print("BinaryInteger, Comparable 준수 \(self)")
}
}
extension SelfPrintable where Self: CustomStringConvertible {
func printSelf() {
print("CustomStringConvertible 준수 \(self)")
}
}
extension SelfPrintable {
func printSelf() {
print("나머지 \(self)")
}
}
Int(-8).printSelf()
//BinaryInteger, Comparable 준수
UInt(12).printSelf()
//BinaryInteger, Comparable 준수
String("Presto").printSelf()
//CustomStringConvertible 준수
Double(8.0).printSelf()
//CustomStringConvertible 준수 ???????????????
Person().printSelf()
//나머지
- 제네릭에서 타입 매개변수와 연관 타입의 제약을 추가하는 데 사용할 수 있다.
: 타입 매개변수가 특정 클래스를 상속받았는지, 특정 프로토콜을 준수하는지 표현할 수 있다.
func doubled<T: BinaryInteger>(_ number: T) -> T {
return number * 2
}
func doubled<T>(_ number: T) -> T where T: BinaryInteger {
return number * 2
}
//위 두 함수 같은 표현
func prints<T: CustomStringConvertible, U: CustomStringConvertible>(first: T, second: U) {
print(first, second)
}
func prints<T, U>(first: T, second: T) where T: CustomStringConvertible, U: CustomStringConvertible {
print(first, second)
}
//위 두 함수 같은 표현
- where 절을 다른 패턴과 조합하여 원하는 추가 요구사항을 자유롭게 추가할 수 있다.
- 익스텐션, 제네릭에 사용하여 프로토콜 또는 타입에 대한 제약을 추가할 수 있다.
- 훨씬 명확하고 간편하게 표현할 수 있다.