2017-01-13 6 views
5

と呼ばれる一般的な方法の句が間違ったジェネリックオーバーロード関数が

を無視した場合、私はあなたの場合は(あなたが運動場でコードをコピーすることができスウィフト3での簡単なユースケースを作った理由を私は理解しようとしています

//MARK: - Classes 

protocol HasChildren { 
    var children:[Human] {get} 
} 

class Human {} 

class SeniorHuman : Human, HasChildren { 
    var children: [Human] { 
     return [AdultHuman(), AdultHuman()] 
    } 
} 

class AdultHuman : Human, HasChildren { 
    var children: [Human] { 
     return [YoungHuman(), YoungHuman(), YoungHuman()] 
    } 
} 

class YoungHuman : Human {} 

//MARK: - Generic Methods 

/// This method should only be called for YoungHuman 
func sayHelloToFamily<T: Human>(of human:T) { 
    print("Hello \(human). You have no children. But do you conform to protocol? \(human is HasChildren)") 
} 

/// This method should be called for SeniorHuman and AdultHuman, but not for YoungHuman... 
func sayHelloToFamily<T: Human>(of human:T) where T: HasChildren { 
    print("Hello \(human). You have \(human.children.count) children, good for you!") 
} 

ここで、いくつかのテストを実行してみましょう。我々が持っている場合:

let senior = SeniorHuman() 
let adult = AdultHuman() 

print("Test #1") 
sayHelloToFamily(of: senior) 

print("Test #2") 
sayHelloToFamily(of: adult) 

if let seniorFirstChildren = senior.children.first { 
    print("Test #3") 
    sayHelloToFamily(of: seniorFirstChildren) 

    print("Test #4") 
    sayHelloToFamily(of: seniorFirstChildren as! AdultHuman) 
} 

を出力は、次のとおりです。

Test #1 
Hello SeniorHuman. You have 2 children, good for you! 

Test #2 
Hello AdultHuman. You have 3 children, good for you! 

Test #3 
Hello AdultHuman. You have no children. But do you conform to protocol? true 
//Well, why are you not calling the other method then? 

Test #4 
Hello AdultHuman. You have 3 children, good for you! 
//Oh... it's working here... It seems that I just can't use supertyping 

うーん...どうやら、動作するようにwhereプロトコル句のために、私たちはその中のプロトコルに準拠し、強力なタイプを渡す必要があります定義。

テスト#3では、指定されたインスタンスが実際にHasChildrenプロトコルに準拠していることが明らかであっても、スーパータイプを使用するだけでは不十分です。

私はここで何が欠けているのですか?何が起こっているのか、またはwhere句に関する詳細や一般的なサブタイピングとその動作についての情報を提供するリンクがありますか?

私はいくつかの便利なリソースを読みましたが、どれも、それは働いていない理由についての網羅的な説明を持っていると思わない:

答えて

3

チェックタイプ

インスタンスが 特定のサブクラス型であるかどうかをチェックするために型チェック演算子(is)を使用。型チェック演算子は、 インスタンスがそのサブクラスタイプの場合はtrueを返し、そうでない場合はfalseを返します。

引数がコンパイル時に解決される型チェックオペレータisが(seniorFirstChildrenにバインドさ)AdultHumanのインスタンスの最初のchildren部材を用いsayHelloToFamilyへのコールのオーバーロード解決一方、ランタイムに解決されます(この場合はHumanと入力されており、HasChildrenに準拠していません)。 がAdultHumanインスタンス(不安全なas! AdultHumanを使用)であることをコンパイラに明示的に伝えると、当然のことながらコンパイラはこの情報を利用してより特定のオーバーロードを選択します。

関連する問題