在Swift中测试泛型时,我遇到了这个问题,无法找到答案。
说我有以下代码:
protocol Component {
}
protocol Contains {
associatedtype CompType: Component
var components: [CompType] { get set }
}
在这里,实现Contains
的类型应该能够存储实现其类型别名指定的Component
协议的任何类型。如果我将代码扩展到以下代码,它将按预期工作。
protocol Component {
}
struct SomeComponent: Component {
init() {
}
}
struct AnotherComponent: Component {
init() {
}
}
protocol Contains {
associatedtype CompType: Component
var components: [CompType] { get set }
}
struct Container: Contains {
typealias CompType = SomeComponent
var components: [SomeComponent]
}
var x = Container(components: [SomeComponent()]) // works perfectly!
var y = Container(components: [AnotherComponent()]) // fails as expected
最后一个问题:是否可以使Container.components
同时接受SomeComponent
和AnotherComponent
,但拒绝实现Component
协议的其他类型?换句话说,typealias
可以容纳一种以上的类型吗?
谢谢!
答案 0 :(得分:2)
您可以遵循多种协议
typealias CompType = SomeComponent & AnotherComponent
或者您可以更改逻辑
protocol Component {
}
struct SomeComponent: Component {
init() {
}
}
struct AnotherComponent: Component {
init() {
}
}
protocol Contains {
var components: [Component] { get set }
}
struct Container: Contains {
var components: [Component]
}
var x = Container(components: [SomeComponent()])
var y = Container(components: [AnotherComponent()])
答案 1 :(得分:0)
类型别名用于解析通用关联类型。它必须明确地将其解析为一种类型。那就是分辨率。
嗯,您的设置方式可以且必须是任何组件采用者。这就是这行的意思:
associatedtype CompType: Component
您使用了Component的通用约束。如果那不是您想要的,就不应该那样做。正如其他人所建议的那样,如果只希望SomeComponent和AnotherComponent满足通用约束,那么您将需要使用只有SomeComponent和AnotherComponent采用的协议。
答案 2 :(得分:0)
我认为您根本不需要associatedtype
protocol Component {
}
struct SomeComponent: Component {
init() {
}
}
struct AnotherComponent: Component {
init() {
}
}
protocol Contains {
var components: [Component] { get set }
}
struct Container: Contains {
var components: [Component]
}
var x = Container(components: [SomeComponent()])
var y = Container(components: [AnotherComponent()])
需要指定类型时,在协议上使用associatedtype
。
在这种情况下,您不想指定,因为您希望能够接受协议的符合者p>