2017-06-12 5 views
0

私は遊び場にいくつかのサンプルコードを書いていて、SwiftのStrideableプロトコルに準拠する2つの値の距離を返す関数を求めていましたので、distance(to other: Self) -> Self.Stride関数。Generic Where Swiftで関連付けられた型のあいまいさ

func distanceFrom<T: Strideable, U>(_ a: T, to b: T) -> U where T.Stride == U 
{ 
    return a.distance(to: b) 
} 

しばらくの間、この機能を観察した後、私はストライドがaからかbから、where句に1を使用していたかわからなかったことに気づき、次のように私の実装でした。私が理解するところでは、abは、Strideの異なる関連タイプを定義することが可能です。また、a.Stride == b.Strideを確実にするためのステートメントは作成していませんが、where節を展開することができます。

だから、等価性を確認するのにどれがUになるのでしょうか?明確にするために、問題はこの特定のコードブロックではなく、むしろこのあいまいさが存在する状況である。

答えて

1

abは同じタイプです。上記のコードはコンパイルしますが、なぜなら、彼ら(areturn a.distance(to: b)がコンパイルされないでしょう

func bar<T: Strideable, V: Strideable, U>(_ a: T, to b: V) -> U where T.Stride == U, V.Stride == U { 
    return a.distance(to: a) //Trivial return statement (see explanation below) 
} 

と:あなたは彼らが異なるStrideableタイプになりたかった場合は、関数のシグネチャは次のように表示されていることなStrideableに準拠した他の一般的なパラメータを追加しますb)は異なるタイプであり、Swift3のdistanceの定義はpublic func distance(to other: Self) -> Self.Strideです(この機能が呼び出されるStrideableと同じタイプにotherを制限するSelfの使用に注意してください)。結論として、あなたはabを異なるタイプにすることができますが、あなたのアプリケーションではそうするのは意味がありません。

さまざまなタイプの元の投稿コードを呼び出せないというさらなる証拠として、添付の Playground screenshotを参照してください。異なるタイプの使用時にエラーが表示されます。

ただし、これはプレイグラウンドで正常に動作します。

func distanceFrom<T: Strideable, U>(_ a: T, to b: T) -> U where T.Stride == U { 
    return a.distance(to: b) 
} 


let doubleFoo: Double = 4.5 
let intFoo: Double = 4 

let g = distanceFrom(doubleFoo, to: intFoo) // gives me a double of -0.5 

これが役立ちます。

+0

私は、aとbはどちらもStrideableプロトコルに準拠していると信じていますが、それらは異なるタイプである可能性があります。私は、この関数をIntとbをDoubleにして呼び出すことをテストし、コンパイルして期待通りに実行します。 – tnev

+0

私の回答に追加したスクリーンショットとコードスニペットを使用して、もう一度お試しください。私は彼ら(両方のTの)が同じタイプでなければならないと信じています。 – Underhill

関連する問題