我想使用通用协议类型作为函数返回类型,如下所示:
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>()
}
}
Run Code Online (Sandbox Code Playgroud)
但是这个代码编译错误抱怨:
有没有办法用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>()
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定要从返回类型中获取协议将为您带来什么好处。假设您的示例只是实际代码的简化,并且您希望能够返回符合的任意实例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)}
}
Run Code Online (Sandbox Code Playgroud)
class Factory {
func createC<T>() -> AnyP<T> {
return AnyP(C<T>())
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
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>()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4968 次 |
| 最近记录: |