我想使用通用协议类型作为函数返回类型,如下所示:
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>() } }
>不能专门化非泛型类型’P’
>通用参数“T”未在函数签名中使用
有没有办法用Swift实现类似的功能?
解决方法
问题是你不能使用语法P< T>. P是一个协议,意味着它不能被视为泛型类型(不能专门化非泛型类型’P’),即使它可能具有给定的关联类型.
事实上,因为它有一个关联类型,你现在甚至不能直接使用协议类型本身 – 你只能将它用作通用约束.
解决您的问题的一个方法是简单地将您的功能签名更改为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>()) } }