Swift协议通用作为函数返回类型 [英] Swift protocol generic as function return type
问题描述
我想使用泛型协议类型作为函数返回类型,如下所示:
I want to use generic protocol type as a function return type like this:
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>()
}
}
但是这段代码编译出错,抱怨:
But this code compile with errors complained:
- 无法专用非泛型类型'P'
- 函数签名中不使用泛型参数'T'
- Cannot specialize non-generic type 'P'
- Generic parameter 'T' is not used in function signature
是否有任何方法可以实现与Swift类似的功能?
Is there any way to achieve similar function with Swift?
推荐答案
问题是您无法使用语法 P< T>
。 P
是一个协议,这意味着它不能被当作泛型类型(不能专用非泛型类型'P'$ c $即使它可能有
。
The problem is you cannot use the syntax P<T>
. P
is a protocol, meaning it can't be treated as a generic type (Cannot specialize non-generic type 'P'
), even though it may have a given associatedtype
.
事实上,因为它有一个 associatedtype
,你现在甚至不能直接使用协议类型 - 你只能用它作为通用约束。
In fact, because it has an associatedtype
, you now can't even use the protocol type itself directly – you can only use it as a generic constraint.
解决您的问题仅仅是将您的函数签名更改为 createC< T>() - >
The solution to your problem is simply to change your function signature to createC<T>() -> C<T>
, as that's exactly what it returns!
class Factory {
func createC<T>() -> C<T> {
return C<T>()
}
}
我不完全确定你认为你能从这里返回一个协议类型而获得什么。如果你的代码只是一个简化,并且你希望能够返回一个符合 P
的任意实例,你可以使用 type erasure 。
I'm not entirely sure what you think you would gain from being able to return a protocol type here. If your code is just a simplification and you want to be able to return an arbitrary instance that conforms to P
, you could use a 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>())
}
}
这篇关于Swift协议通用作为函数返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!