[Swift] protocol extension에서 기본 매개 변수를 사용할 때 주의해야 할 방법의 선언

11806 단어 SwiftiOS
그거 시험 쓸 때 발생한...
제품 코드에서 protocol extension을 사용하는 부분은 mock으로 바꾸려고 하는데 왜 mock이라고 부르는 방법이 없습니까!
모듈에서 프로토콜을 정의해야 하는 방법이 확실합니다...

작성된 코드(단순화)

protocol SomeProtocol {
    func hoge(string: String)
}

// プロダクトコードのときはこちらを通ってほしい
extension SomeProtocol {
    func hoge(string: String = "") {
        print("\(string)SomeProtocol")
    }
}

// テスト用のモックだと思ってください
// テスト時はこちらを通したい
class SomeClass: SomeProtocol {
    func hoge(string: String = "") {
        print("\(string)SomeClass")
    }
}

// 型としてはプロトコル
let some: SomeProtocol = SomeClass()
some.hoge(string: "hello ") // これらの
some.hoge()                 // 出力は・・・?
어떤 프로토콜hoge(string:)의 방법은protocol extension과SomeClass가 모두 실현된 상태를 정의했다.
이때 유형SomeProtocol으로 실체는 SomeClass의 속성에서 호출hoge()된다.
기대한 결과로 어느 것이든 SomeClass라고 불렀으면 좋겠다hoge().
실제 결과는 다음과 같다.
some.hoge(string: "hello ") // => hello SomeClass
some.hoge()                 // => SomeProtocol
some.hoge(string: "hello ")에 관해서는 기대했던 대로 SomeClass 방법이 호출되었지만 some.hoge()protocol extension 방법이 호출되었다.

무슨 일이 있었는지


protocol extension의 행동에 대해 좋은 기사가 있으니 꼭 읽어주세요.
Swift 프로토콜 연장 트랩
이번 코드와 관련된 부분만 대충 정리하면
  • 협의 주체에 선언적인 방법을 호출할 때 동적 분배
  • 협의 주체에 성명이 없는 상황에서 정적 분배
  • 라는 뜻이다.
    협의 주체상hoge(string:)라벨을 소지하는 방법만 있고 라벨이 없는hoge()라벨은 선언이 없다는 것을 이미 알고 계신 것 같습니다.
    따라서 some.hoge(string: "hello ")는 실체SomeClass의 방법이고, some.hoge()는 유형SomeProtocol의 방법으로 불린다.

    수정


    합의 자체에 없는hoge() 선언은 문제이고 추가되면 해결된다.
    기본 매개 변수는 아무런 의미가 없기 때문에 삭제하는 중입니다.
    protocol SomeProtocol {
        func hoge() // 追加
        func hoge(string: String)
    }
    
    extension SomeProtocol {
        func hoge() { // 追加
            self.hoge(string: "")
        }
    
        func hoge(string: String) {
            print("\(string)SomeProtocol")
        }
    }
    
    class SomeClass: SomeProtocol {
        func hoge() { // 追加
            self.hoge(string: "")
        }
    
        func hoge(string: String) {
            print("\(string)SomeClass")
        }
    }
    
    let some: SomeProtocol = SomeClass()
    some.hoge(string: "hello ") // => hello SomeClass
    some.hoge()                 // => SomeClass
    
    이것은 기대했던 결과와 같다.


    사실 위의 전선은 좀 더 게으름을 피울 수 있다.
    protocol SomeProtocol {
        //func hoge()
        func hoge(string: String)
    }
    
    extension SomeProtocol {
        func hoge() {
            self.hoge(string: "")
        }
    
        func hoge(string: String) {
            print("\(string)SomeProtocol")
        }
    }
    
    class SomeClass: SomeProtocol {
    //    func hoge() {
    //        self.hoge(string: "")
    //    }
    
        func hoge(string: String) {
            print("\(string)SomeClass")
        }
    }
    
    let some: SomeProtocol = SomeClass()
    some.hoge(string: "hello ") // => hello SomeClass
    some.hoge()                 // => SomeClass
    
    주석 OUT 섹션과 위 코드의 차이점.
    이때some.hoge()는 한 번SomeProtocol.hoge()을 통해SomeClass.hoge(string:) 호출된다.
    이번hoge()은 내용이 없는 방법이기 때문에 이것도 괜찮지만 일반적으로 합의선언으로 실시하는 것이 좋다.

    끝말


    protocol extension은 코드를 공통화하는 매우 편리한 기능이지만 중간에 링크를 실은 글처럼 불가사의한 행위가 있을 수 있으므로 주의해야 한다
    기본 매개 변수도 편리하지만, 방법의 라벨을 쓰지 않으면 라벨이 있는 방법과 다르다고 판단됩니다
    이것 때문에 막힌 사람 없나요?
    잘 모르시겠지만 참고가 됐으면 좋겠어요

    좋은 웹페이지 즐겨찾기