上下文是我有一个类A
,它有很多属性,但我只想暴露其中的一些,其中一个是泛型类型。
然后我尝试为A创建一个通用协议(可能是一个错误的名字?)。
看起来很好但是当我尝试在方法中使用协议而不是结构时,它不会编译。
有什么建议吗?
protocol AProtocol {
associatedtype T
var t: T? { get }
}
struct A<Type>: AProtocol {
typealias T = Type
var t: Type?
var a: Int
var b: Int
var c: Int
var d: Int
var e: Int
}
struct Main {
func show<T: Decodable>(a: AProtocol<T>) { // error: Cannot specialize non-generic type 'AProtocol'
}
}
修改
下面的代码片段是在我从@ Sweeper的答案更新后,对实施进行了轻微的调整,因为最初在我的项目中它是一个闭包。
protocol AProtocol {
associatedtype T
var t: T? { get }
}
struct A<Type>: AProtocol {
typealias T = Type
var t: Type?
var a: Int?
var b: Int?
var c: Int?
var d: Int?
var e: Int?
}
struct Main {
func show<T, U>(completion: (U) -> Void) where T: Decodable, U: AProtocol, U.T == T {
let a = A<Int>()
completion(a) //error: '(A<Int>) -> Void' is not convertible to '(U) -> Void'
}
}
你能解释为什么这不起作用吗?
答案 0 :(得分:2)
您无法使用具有相关类型的协议。具有关联类型的协议与通用协议不同。后者在Swift中不存在。
在这种情况下,您通常要做的是向方法引入一个新的通用参数U
并将其约束到协议:
func show<T, U>(a: U) where T: Decodable, U : AProtocol, U.T == T {
}
3个限制是:
T
必须符合Decodable
U
必须符合AProtocol
U.T
必须与T
有道理,对吧?