티스토리 뷰

[시작]


- 스위프트의 표준 라이브러리에서 타입과 관련된 부분은 대부분 클래스가 아닌 구조체로 구현됨

- 프로토콜, 익스텐션, 제네릭 등을 활용하여 상속을 받지 못하는 구조체로 다양한 공통 기능을 구현함



[프로토콜 초기 구현]


- 프로토콜 지향 프로그래밍의 핵심 개념

- 프로토콜을 익스텐션에서 구현함

 : 저장 프로퍼티는 익스텐션에서 구현할 수 없으므로 각각의 타입에서 직접 구현해야 함

- 프로토콜 초기 구현 : 프로토콜의 요구사항을 익스텐션을 통해 구현하는 것.

- 익스텐션에서 구현한 기능을 사용하고 싶지 않다면 각각의 타입에서 재정의하면 된다.


protocol SelfPrintable {

    func printSelf()

}

extension SelfPrintable where Self: Container {

    func printSelf() {

        print(items)

    }

}


protocol Container: SelfPrintable {

    associatedtype ItemType

    var items: [ItemType] { get set }

    var count: Int { get }

    mutating func append(item: ItemType)

    subscript(i: Int) -> ItemType { get }

}

extension Container {

    mutating func append(item: ItemType){

        items.append(item)

    }

    var count: Int {

        return items.count

    }

    subscript(i: Int) -> ItemType {

        return items[i]

    }

}


protocol Popable: Container {

    mutating func pop() -> ItemType?

    mutating func push(_ item: ItemType)

}

extension Popable {

    mutating func pop() -> ItemType? {

        return items.removeLast()

    }

    mutating func push(_ item: ItemType) {

        self.append(item: item)

    }

}


protocol Insertable: Container {

    mutating func delete() -> ItemType?

    mutating func insert(_ item: ItemType)

}

extension Insertable {

    mutating func delete() -> ItemType? {

        return items.removeFirst()

    }

    mutating func insert(_ item: ItemType) {

        self.append(item: item)

    }

}



프로토콜의 구현을 익스텐션에서 미리 했으므로 코드를 작성할 수 있다.


- 프로토콜 초기구현을 한 프로토콜을 채택했다면 상속도, 추가 구현도 필요하지 않다.

- 초기구현을 한 프로토콜을 구조체, 열거형 등에 채택하게 하여 기능을 얼마든지 추가할 수 있다.



[맵, 필터, 리듀스 직접 구현해보기]


struct Stack<Element>: Popable {

    var items: [Element] = [Element]()

    

    func map<T>(transform: (Element) -> T) -> Stack<T> {

        var transformedStack: Stack<T> = Stack<T>()

        for item in items {

            transformedStack.items.append(transform(item))

        }

        return transformedStack

    }

    

    func filter(includeElement: (Element) -> Bool) -> Stack<Element> {

        var transformedStack: Stack<Element> = Stack<Element>()

        for item in items {

            if includeElement(item){

                transformedStack.items.append(item)

            }

        }

        return transformedStack

    }

    

    func reduce<T>(_ initial: T, combine: (T, Element) -> T) -> T {

        var result: T = initial

        for item in items {

            result = combine(result, item)

        }

        return result

    }

}


map : 호출한 요소에서 transform을 거쳐 어떠한 타입 T 형태의 Stack을 반환

filter : 호출한 요소에서 includeElement를 검사하여 true인 것만 반환

reduce : 초기값과 하나로 만드는 데 사용될 클로저를 두어 어떠한 타입 T 형태의 값을 반환



[기본 타입 확장]


- 스위프트 표준 라이브러리에 정의된 타입에 사용자 정의 프로토콜과 프로토콜 초기 구현을 활용하여 기능을 추가할 수 있다.


protocol SelfPrintable {

    func printSelf()

}

extension SelfPrintable {

    func printSelf() {

        print(self)

    }

}


extension Int: SelfPrintable {}


1967982.printSelf() //1967982



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

25장 패턴  (0) 2018.04.28
24장 타입 중첩  (0) 2018.04.28
22장 제네릭  (0) 2018.04.27
21장 익스텐션  (0) 2018.03.07
20장 프로토콜  (0) 2018.03.01
댓글
최근에 올라온 글
최근에 달린 댓글
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
글 보관함