[英]Swift protocol generic as function return type
我想使用通用協議類型作為函數返回類型,如下所示:
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>()
}
}
但是這段代碼編譯時出現錯誤:
有沒有辦法用Swift實現類似的功能?
問題是您不能使用語法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
的任意實例。 在這種情況下,您可以使用類型擦除:
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>())
}
}
Swift 5.1 支持使用 Opaque 類型返回關聯類型。 使用 opaque 類型,您的代碼構建成功。 參考
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>() -> some P {
return C<T>()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.