티스토리 뷰

Swift/야곰의 스위프트

26장 where 절

할루루 2018. 4. 30. 13:34

[시작]


- 특정 패턴과 결합하여 조건을 추가하는 역할



[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


옵셔널 패턴과 함께 where절이 사용된 예


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")

    }

}


타입캐스팅 패턴과 함께 where절이 사용된 예


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 절을 다른 패턴과 조합하여 원하는 추가 요구사항을 자유롭게 추가할 수 있다.

- 익스텐션, 제네릭에 사용하여 프로토콜 또는 타입에 대한 제약을 추가할 수 있다.

- 훨씬 명확하고 간편하게 표현할 수 있다.




'Swift > 야곰의 스위프트' 카테고리의 다른 글

2회독 정리  (0) 2018.10.03
27장 ARC  (0) 2018.05.01
25장 패턴  (0) 2018.04.28
24장 타입 중첩  (0) 2018.04.28
23장 프로토콜 지향 프로그래밍  (0) 2018.04.28
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함