let tupleValues = [(1, 2), (1, -1), (1, 0), (0, 2)]
for tupleValue in tupleValues {
switch tupleValue {
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(tupleValue)
}
}
// x == 1
// x == -y
// x > y
// y == 2
var repeatCount: Int = 0
for tuple in tupleValues {
switch tuple {
case let (x, y) where x == y && repeatCount > 2: print("x == y")
case let (x, y) where repeatCount < 2: print("\(x), \(y)")
default: print("아무것도 아님")
}
repeatCount += 1
}
// 1, 2
// 1, -1
// 아무것도 아님
// 아무것도 아님
let arrayOptionalInts: [Int?] = [2, 4, nil, 1, 5, nil]
for case let number? in arrayOptionalInts where number > 2 {
print("2보다 큰 정수를 찾아라! \(number)")
}
// 2보다 큰 정수를 찾아라! 4
// 2보다 큰 정수를 찾아라! 5
let anyValue: Any = "가나다"
switch anyValue {
case let value where value is Int: print("\(value)는 Integer입니다.")
case let value where value is String: print("\(value)는 String입니다.")
case let value where value is Double: print("\(value)는 Double입니다.")
default: print("알 수 없는 타입입니다.")
}
// 가나다는 String입니다.
let things: [Any] = [1, 2.3, "가나다", 4, 9.84, "와우우", 0, 0.0]
for thing in things {
switch thing {
case 0 as Int: print("0은 Int처럼 존재한다")
case 0.0 as Double: print("0.0은 Double처럼 존재한다.")
case let someInt as Int: print("\(someInt) 정수입니다.")
case let someDouble as Double: print("\(someDouble) Double입니다.")
default: print("암것도 아닙니다.")
}
}
// 1 정수입니다.
// 2.3 Double입니다.
// 암것도 아닙니다.
// 4 정수입니다.
// 9.84 Double입니다.
// 암것도 아닙니다.
// 0은 Int처럼 존재한다
// 0.0은 Double처럼 존재한다.
protocol SelfPrintable {
func printSelf()
}
struct Person: SelfPrintable {
}
extension Int: SelfPrintable { }
extension String: SelfPrintable { }
extension UInt: SelfPrintable { }
extension Double: SelfPrintable { }
extension SelfPrintable where Self: FixedWidthInteger, Self: SignedInteger {
func printSelf() {
print("이 타입은 FixedWidthInteger와 SignedInteger를 준수하면서 SelfPrintable를 준수한 타입\(type(of: self))입니다.")
}
}
extension SelfPrintable where Self: CustomStringConvertible {
func printSelf() {
print("이 타입은 CustomStringConvertible를 준수하면서 SelfPrintable를 준수한 타입\(type(of: self))입니다.")
}
}
extension SelfPrintable {
func printSelf() {
print("그 외 SelfPrintable를 준수하는 타입 \(type(of: self))")
}
}
Int(-9).printSelf()
// 이 타입은 FixedWidthInteger와 SignedInteger를 준수하면서 SelfPrintable를 준수한 타입Int입니다.
UInt(8).printSelf()
// 이 타입은 CustomStringConvertible를 준수하면서 SelfPrintable를 준수한 타입UInt입니다.
String("Peter").printSelf()
// 이 타입은 CustomStringConvertible를 준수하면서 SelfPrintable를 준수한 타입String입니다.
Double(8.0).printSelf()
// 이 타입은 CustomStringConvertible를 준수하면서 SelfPrintable를 준수한 타입Double입니다.
Person().printSelf()
// 그 외 SelfPrintable를 준수하는 타입 Person
func double<T>(integerValue: T) -> T where T: BinaryInteger {
return integerValue * 2
}
func compareTwoValue<S1, S2>(_ a: S1, _ b: S2) where S1: Sequence, S2: Sequence, S1.Element == S2.Element {
...
}
protocol Container {
associatedtype Item where Item: BinaryInteger
var count: Int { get }
mutating func append(_ item: Item)
}
protocol Talkable { }
protocol CallToAll {
func callToAll()
}
struct Person: Talkable { }
struct Animal { }
extension Array: CallToAll where Element: Talkable {
func callToAll() {
print("여러부운")
}
}
let people: [Person] = []
let animals: [Animal] = []
people.callToAll()
// 여러부운
animals.callToAll() // 컴파일 오류
이와 같이 where 절은 다른 패턴과 조합하면 원하는 추가 요구사항을 자유롭게 더할 수 있으며, 익스텐션과 제네릭에 사용함으로써 프로토콜 또는 타입에 대한 제약을 추가해줄 수도 있습니다. 조건 구문이나 논리 연산으로 구현한 코드보다는 훨씬 명확하고 간편하게 사용할 수 있습니다.
자료 출처: 야곰 스위프트 프로그래밍 3판
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."