2016-06-01 96 views
5

我要使用通用的協議類型爲函數的返回類型是這樣的:斯威夫特協議通用的函數返回類型

protocol P { 
    associatedtype T 
    func get() -> T? 
    func set(v: T) 
} 

class C<T>: P { 
    private var v: T? 
    func get() -> T? { 
    return v 
    } 
    func set(v: T) { 
    self.v = v 
    } 
} 

class Factory { 
    func createC<T>() -> P<T> { 
    return C<T>() 
    } 
} 

但這個代碼有錯誤編譯抱怨:

  1. 不能專注非通用類型 'P'
  2. 通用參數 'T' 是不是在功能簽名使用

有什麼辦法可以實現與Swift類似的功能嗎?

+0

哪些行有錯誤?我認爲我有一個好主意,其中#2不是#1。 – tktsubota

+0

@TroyT代碼行'func createC () - > P { – ufosky

回答

5

問題是你不能使用語法P<T>P是一個協議,這意味着它不能被視爲一般類型(Cannot specialize non-generic type 'P'),即使它可能有給定associatedtype

事實上,因爲它有一個associatedtype,你現在甚至不能直接使用的協議類型本身 - 你只能用它作爲通用約束。

解決您的問題只是將您的功能簽名更改爲createC<T>() -> C<T>,因爲這正是它返回的!

class Factory { 
    func createC<T>() -> C<T> { 
     return C<T>() 
    } 
} 

我不完全確定你認爲你能從這裏返回協議類型獲得什麼。如果您的代碼僅僅是一個簡化,並且您希望能夠返回符合P的任意實例,則可以使用type erasure

class AnyP<T> : P { 

    private let _get :() -> T? 
    private let _set : (T) ->() 

    init<U:P where U.T == T>(_ base:U) { 
     _get = base.get 
     _set = base.set 
    } 

    func get() -> T? {return _get()} 
    func set(v: T) {_set(v)} 
} 

class Factory { 
    func createC<T>() -> AnyP<T> { 
     return AnyP(C<T>()) 
    } 
}