swift & iOS/swift

[swift] 기존 데이터 타입에 추가 기능 작성하기: extension

whale3 2022. 2. 8. 18:30

지하철이나 버스 노선을 필요에 따라 연장하거나 노선을 추가 개통하는 것처럼 스위프트에서도 기존 데이터 타입에 필요에 따라 새로운 기능을 추가하게 해주는 도구인 extension이 있다. 기존의 클래스, 구조체, 열거형, 프로토콜 및 기타 데이터 타입에 기능을 작성할 수 있다. 

 

extension은 아래처럼 사용한다. 또한 extension이 프로토콜을 채택할 수도 있다. extension이 프로토콜을 채택할 수 있다는 특징을 이용하여 viewController가 여러 개의 프로토콜을 채택하고 컨트롤러 내부 소스가 마구 복잡해질 때 extension을 만들고 컨트롤러 대신 이 extension이 필요한 프로토콜을 하나씩 채택한 후, 해당 extension 내부에서 채택한 프로토콜을 준수하는 방법으로 컨트롤러 내부 소스를 줄일 수도 있더라. (공식문서)

 

// 출처: https://docs.swift.org/swift-book/LanguageGuide/Extensions.html

extension SomeType {
    // 추가하려는 새로운 기능 작성
}

extension SomeType: SomeProtocol, AnotherProtocol {
    // implementation of protocol requirements goes here
    // 채택한 프로토콜을 준수하는 내용을 작성
}

 

기존 데이터 타입인 Double에 computed property를 추가할 수도 있고 (computed property는 추가 작성할 수 있지만 stored property는 안됨)

 

// 출처: https://docs.swift.org/swift-book/LanguageGuide/Extensions.html#ID152

extension Double {
    var km: Double { return self * 1_000.0 }
    var m: Double { return self }
    var cm: Double { return self / 100.0 }
    var mm: Double { return self / 1_000.0 }
    var ft: Double { return self / 3.28084 }
}
let oneInch = 25.4.mm
print("One inch is \(oneInch) meters")
// Prints "One inch is 0.0254 meters"

let threeFeet = 3.ft
print("Three feet is \(threeFeet) meters")
// Prints "Three feet is 0.914399970739201 meters"

 

기존 데이터 타입인 Int에 메소드로 새로 작성할 수 있다. 

 

// 출처: https://docs.swift.org/swift-book/LanguageGuide/Extensions.html#ID154

extension Int {
    func repetitions(task: () -> Void) {
        for _ in 0..<self {
            task()
        }
    }
}

3.repetitions {
    print("Hello!")
}
// Hello!
// Hello!
// Hello!

 

프로토콜에도 extension을 사용할 수 있다. 원래 프로토콜을 채택하면 optional이 아닌 이상 그 안에 있는 메소드들을 다 구현해야 하는데 extension을 사용하면 메소드를 구현하지 않아도 기본 액션을 취할 수 있도록 할 수 있다. 

 

// 출처: https://docs.swift.org/swift-book/LanguageGuide/Protocols.html#ID521
// 위의 예제를 간단하게 변경하였다. 

protocol RandomNumberGenerator {
    func randomBool() -> Bool
}

struct Dice: RandomNumberGenerator {
    
}

 

위처럼 프로토콜을 채택했는데 그 안의 메소드를 구현하지 않으면 채택한 프로토콜을 준수하지 않았다는 내용의 경고 메시지가 나온다. 

 

 

여기에서 위 프로토콜에 대한 extension을 아래처럼 작성하면 이 프로토콜을 채택한 구조체 내에 메소드를 구현하지 않아도 경고 메시지가 나오지 않고 메소드를 호출할 수도 있다. 

 

extension RandomNumberGenerator {
    func randomBool() -> Bool {
        return true
    }
}

let myDice = Dice()
myDice.randomBool()

 

저번에 프로토콜에 대한 포스팅을 작성하면서 POP(protocol oriented programming) 프로토콜 지향 프로그래밍이란 것을 잠깐 적었는데 'extension으로 기본적인 것을 구현..'이라는 말이 이제야 조금 이해가 되는 것 같다. 

 

POP(protocal oriented programming)
프로토콜 단위로 묶어 표현하고 extension으로 기본적인 것을 구현하여 단일 상속의 한계를 극복하고자 하는 프로그래밍 기법이라고 한다. ...

https://what-whale-wants-to-say-is.tistory.com/94

 

[swift] 프로토콜 protocol

프로토콜이 좀 생소해서 항상 챙겨보고 있는 아래 유튜브 영상을 많이 참고했다. 아 물론 swift 공식문서도... https://www.youtube.com/watch?v=p19mUgg1CFQ&list=PLJqaIeuL7nuFbWKMhG8-xLzF1T7gIPr8Z&index=69..

what-whale-wants-to-say-is.tistory.com

 

 

반응형