ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift Generic - 2
    Programming/Swift(iOS) 2021. 4. 6. 14:50
    728x90

    배열 sort함수를 예로 들어보죠. 

     

    sort는 배열 안에 담긴 객체 타입이 어떤것이냐에 따라서 다른데요.

     

    Int, Float, String등 시스템에서 제공하는 기본타입은 sorted가 됩니다.

    하지만 사용자가 구현한 객체 타입은 되지 않습니다. 

     

    이유는 기본 타입의 경우에는 'Comparable' Protocol을 미리 준수했기 때문입니다.

    사용자가 만든 객체의 경우에도 동일하게 'Comparable' Protocol을 준수하면 가능합니다. 

     

    갑자기 제너릭 하다가 프로토콜로 빠져버렸는데요. 

     

    sorted는 타입에 따라서 모두 제공을 하기 때문에 제너릭으로 구현되어 있습니다. 

    원형을 찾아보면 Self.Element로 되어 있습니다.

    @inlinable public func sorted() -> [Self.Element]

     

    배열안에서 최솟값을 찾는 함수를 만들어보죠

    sorted를 하고 첫번째 원소를 반환시키면 될 것 같습니다. 

     

    func lowest(_ array:[Int]) -> Int? {
        // 1) 오름 차순 정렬
        let sorted = array.sorted()
        // 정렬된 배열에서 첫번째 원소 반환
        return sorted.first
    }
    
    let arr1:[Int] = [5,4,3,2,1]
    

     

    이 함수를 제너릭하게 만들려면 어떻게 해야될까요?

    T라는 객체인데, 이것은 Comparable protocol을 만족한다고 표시를 해줘야합니다.

    func lowest<T:Comparable>(_ array:[T]) -> T? {
        return array.sorted().first
    }
    

    where를 이용해서 제약을 표현할 수도 있습니다.

    func lowest<T>(_ array:[T]) -> T? where T:Comparable {
        return array.sorted().first
    }
    
    let arr = [10, 9, 8, 7, 6]
    
    //optional을 return 하므로...
    if let result = lowest(arr) {
        print(result)
    }

    그렇다면, 사용자가 만든 객체는 어떻게 해야될까요?

     

    객체에 extension을 통해서 Comparable을 만족시켜주면 됩니다. 

    struct User {
        let age:Int
    }
    
    let arr3 = [User(age: 30), User(age: 20), User(age: 10)]
    
    extension User:Comparable {
        static func <(lhs:User, rhs:User)->Bool{
            return lhs.age < rhs.age
        }
    }
    
    if let result = lowest(arr3) {
        print(result)
    }

    enum은 약간 다릅니다. enum도 comparable protocol을 구현하지 않는 것은 동일하지만, 구현하지 않는 경우에는 case 순서에 따라 자동으로 결정됩니다. 

    enum School {
        case high
        case middle
        case elementary
    }
    
    let arr4:[School] = [.elementary, .middle, .high]
    
    extension School:Comparable {
        static func < (lhs:School, rhs:School) -> Bool {
            switch (lhs, rhs) {
            case (elementary, middle):
                return true
            case (elementary, high):
                return true
            case (middle, high):
                return true
            default:
                return false
            }
        }
    }
    
    
    if let result2 = lowest(arr4) {
        print(result2)
    }
    

    'Programming > Swift(iOS)' 카테고리의 다른 글

    mac os에서 시스템 키체인을 사용하고자 합니다.  (0) 2021.06.10
    Swift Generic - 3  (0) 2021.04.06
    Swift Generic - 1  (0) 2021.04.06
    Swift 오류처리 -3  (0) 2021.04.06
    Swift 오류처리 - 3  (0) 2021.04.06
Designed by Tistory.