2016-07-12 7 views
2

私は、プロトコルとスウィフトで書かれた彼の実装を持っている:すべてが正常に動作今までデフォルトパラメータ

func foo<T: P>(param: T) { 
} 

func foo() { 
    foo(param: A()) 
} 

protocol P { 
} 

struct A: P { 
} 

プロトコルは、いくつかの機能のためのジェネリック型として使用されています。残念ながら、次のエラーで

func foo<T: P>(param: T = A()) { 
} 

:しかし、私は与えられた関数のデフォルトパラメータとしてA()を設定したい

Default argument value of type 'A' cannot be converted to type 'T'.

それとも

func foo<T: P>(param: T = A() as P) { 
} 

let a: P = A() 
func foo<T: P>(param: T = a) { 
} 

返品:

Default argument value of type 'P' cannot be converted to type 'T'

それとも

func foo<T: P>(param: T = A() as T) { 
} 

戻り値:

'A' is not convertible to 'T'; did you mean to use 'as!' to force downcast?

私が間違ってやっていますか?問題はどこだ?私は力を使いたくない

は次のようにキャスト:

func foo<T: P>(param: T = A() as! T) { 
} 

は、事前にありがとうございます。

答えて

3

一般的な関数で非一般的なデフォルトの引数を強制しようとしています。ここで達成しようとしていることを考えるべきでしょう。議論の便宜上

、あなたは、例えば、あなたの関数のシグネチャでTからA()の試行されたキャストを含めることができますが、あなたが失敗した変換(nil)を許可するには、オプションの引数の型を変更する必要があるだろう

func foo<T: P>(param: T? = (A() as? T)) { } 

より音の代替を含むされる - TAあるインスタンスの具体的な非ジェネリック機能(具体的な機能は、一般的なものよりも優先されます)、あなたは含めることができ、その場合には - あなたの一般的な機能に加えて、具体的な関数の関数シグニチャーのデフォルト引数A()例えば。

protocol P { } 
struct A: P { } 
extension Int: P { } 

func foo<T: P>(param: T) { print("called generic foo") } 
func foo(param: A = A()) { print("called A specific foo") } 

foo() // called A specific foo (making use of default arg) 
foo(A()) // called A specific foo 
foo(1) // called generic foo 

非ジェネリックfooAPに準拠していてもと呼ばれることに注意してください(Aは、一般的なfoo作られた使用をした可能性):具体的な機能が優先と矛盾がここにありません。


一方、汎用関数が単一の引数なしで呼び出しを許可したい場合(つまり、デフォルトの引数を使用して)、単純なイニシャライザの青写真をPに含めて、ジェネリック型のインスタンスをデフォルトの引数として初期化することができます。 @Sulthan:s answerを参照してください。

1

あなたが必要とする唯一のものは、プロトコルの初期化子の要件を追加することです:

protocol P { 
    init() 
} 

struct A: P { 
    var x: Int 

    init() { 
     x = 10 
    } 
} 

func foo<T: P>(param param: T = T()) { 
} 

しかし、あなたは別の問題があります。渡されたパラメータの型はジェネリック型の型を決定するので、ジェネリック型を何とか他の方法で指定する必要があります。

関連する問題