我想快速实现这样的目标:
protocol P {}
protocol P1: P {}
class P1Impl: P1 {}
protocol PBase {
associatedtype T: P
var prop: T { get }
}
struct S: PBase {
typealias T = P1 // <---- The problem
// This property is got via DI, so I don't know
// the actual type of it.
@Injected var prop: P1
}
现在的问题是这段代码无法编译,原因是行
typealias T = P1
。编译器想要知道实际类型而不是 P1
(虽然我没有该类型)。
如果协议
P
有必需的静态属性,我会理解这个限制。在这种情况下,我们可以在没有任何实例的情况下获取该属性的值,因此确实需要实际类型。然而在我的例子中没有这样的属性。
不管怎样,我喜欢swift,想快速地解决这个任务。对于这种情况,最佳做法是什么?
附注
我认为仿制药可以有所帮助:
struct S<T: P1>: PBase {
var prop: T
}
但是在这种情况下,我在创建
T
实例时也不知道 S
的类型,因为 DI 返回协议。
正如其中一条评论中提到的,我确实认为可能值得检查
any P
返回值以及您的 associatedtype
要求是否确实需要。否则你可以尝试使用类型擦除:
struct AnyP1: P1 {
var actual: any P1
init(_ actual: any P1) {
self.actual = actual
}
}
这将 P1 实现包装为已知类型,该类型也符合
P1
协议。然后在您的 S
对象中,您应该执行以下操作:
struct S: PBase {
typealias T: AnyP1
var prop: T
}
// Or shorthand
struct S: PBase {
var prop: AnyP1
}
您的
S
现在将始终知道 T
的类型,并且类型擦除将包含实际的底层协议值。