2017-01-23 12 views
1

私はGenericを使用してアプリケーションを開発しています。Swiftはジェネリッククラスのジェネリック関数を使用します

しかし、ジェネリッククラスのジェネリック関数を使用する際に問題があります。

ご存知のように、我々は一般的なように使用します。

class ClassA{ 
    static func myFunction<Type>()->Type where Type : Protocol1, Type : Protocol2{ 
     ... 
     return Type 
    } 
} 


class ClassB{ 
    func myFunction(){ 
     let a : ClassC = ClassA.myFunction() 
    } 
} 

class ClassC : Protocol1, Protocol2{ 

} 

をそして、これはうまく動作します。

class ClassA{ 
    static func myFunction<Type>()->Type where Type : Protocol1, Type : Protocol2{ 
     ... 
     return Type 
    } 
} 


class ClassB<Type : Protocol1, Protocol2>{ 
    func myFunction(){ 
     let a : Type = ClassA.myFunction() 
    } 
} 

そして、このコードは私に、「推論することができませんでしたジェネリックパラメータ 『タイプ』」エラーを与える:

は、しかし、私は何をしたいです。

それは他のジェネリック型を推論するジェネリック型を使用することが可能です...

class ClassB<Type> where Type : Protocol1, Type : Protocol2{ 

しかし、それは全く使用しなかっ:

私が試しましたか?

+0

問題は単に 'ClassB 'です。これは* 2つの*汎用プレースホルダ、TypeとProtocol2を定義しています。あなたは、 'Protocol1'と' Protocol2'の両方に適合する*単一の*汎用プレースホルダ 'Type'を定義する' ClassB 'と言いたいと思っていました。 – Hamish

答えて

1

私はあなたにタイプ推論を混乱させると思います。どのように動作するん:割り当てられた値にa推論感謝のこのケースタイプで

var a = "Some string" 

- それはStringと他には何もすることが知られている:通常、あなたはこのような何かを持っています。

より複雑な例:関数のシグネチャから推測この場合、型は

func returnString() -> String { 
    return "Some string" 
} 
var b = returnString() 

、戻り型から - それはStringであり、それは、その署名に記載されている:-> String。コンパイラは、bStringであることを確実に知っています。

ジェネリック型の推論ではもう少し複雑になります。あなたの機能を見てみましょう:

let a : Type = ClassA.myFunction() 

ここでは何が表示されますか? aは型が不明なので、呼び出す関数から型を推測する必要があります。これをやろう!関数のシグネチャを見てください:

static func myFunction<Type>()->Type where Type : Protocol1, Type : Protocol2 

関数の戻り値の型が順番にどこかから推測しなければならないので、私は、混同されるだろう、この場合には「どこかに」は、正確にあなたが定義された変数の型ですコンパイラとして(本当にどこにもないので)割り当てたい。しかし、変数の型も指定していません。これはまさに「Generic parameter 'Type'を推論できませんでした」というエラーです。式の両辺には未知の型があり、互いに推論する必要があります

ここは動作します:まさにそのための

let a : ClassC = ClassA.myFunction() 

を - あなたは抽象的でないタイプを指定したが、具体的な種類: ClassCと、コンパイラは、それがClassCfunc myFunction ...Typeに置き換えなければならないことを、知っています。

結論として、あなたのような汎用関数では、型推論は、関数から変数の型を推論するのではなく、変数から推論される関数の型を全く違う方向に働くと言います。

+0

ありがとうございます。私はコンパイラが後で型を推論できると思った。 (Class - > Generic Class - > Static Generic Function)のように、しかし私はそれができないと思います。私は本当にあなたの助けをappericiate! –

+0

「* 'a'は不明なタイプです」とはどういう意味ですか?コンパイラは、型が 'Type'でなければならないことを知っています。なぜなら、それが注釈付きであるからです。 – Hamish

+0

@Hamishそれは言葉の最善の選択ではないかもしれませんが、私はアイデアが明確であることを願っています - コンパイラも、あなたは本当に 'タイプ'が本当に何であるか言うことができません。これはどこかで実装されておらず、実際、いくつかの具体的な型のプレースホルダです。 –

関連する問題