[英]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:但是这段代码编译时出现错误:
Is there any way to achieve similar function with Swift?有没有办法用Swift实现类似的功能?
The problem is you cannot use the syntax P<T>
.问题是您不能使用语法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
. P
是一个协议,这意味着它不能被视为泛型类型( Cannot specialize non-generic type 'P'
),即使它可能具有给定的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.事实上,因为它有一个associatedtype
,你现在甚至不能直接使用协议类型本身——你只能将它用作通用约束。
One solution to your problem is to simply change your function signature to createC<T>() -> C<T>
, as that's exactly what it returns.您的问题的一种解决方案是简单地将您的函数签名更改为createC<T>() -> C<T>
,因为这正是它返回的内容。
class Factory {
func createC<T>() -> C<T> {
return C<T>()
}
}
I'm not entirely sure what you would gain from having the return type be a protocol here.我不完全确定将返回类型作为此处的协议会获得什么。 Presumably your example is just a simplification of your actual code and you want to be able to return an arbitrary instance that conforms to P
.据推测,您的示例只是对实际代码的简化,并且您希望能够返回符合P
的任意实例。 In that case, you could use 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 5.1 supports returning associated types using Opaque type. Swift 5.1 支持使用 Opaque 类型返回关联类型。 Using opaque type, your code builds successfully.使用 opaque 类型,您的代码构建成功。 Ref 参考
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.