我在使用符合包含关联类型的协议的 @State 属性时在 SwiftUI 中遇到了问题。此属性包括我需要在运行时修改的关联类型元素的数组。
以前,当该字段为只读时(在协议中声明为 { get }),一切都会按预期工作。然而,一旦我将其设为读写(声明为 { get set }),我遇到了编译错误,没有具体细节。
在 SwiftUI 中使用关联类型的读写属性时,如何解决此编译错误?
struct ContentView: View {
@State var a: any A
var body: some View {
Text("\(a.units.count)") // Command SwiftCompile failed with a nonzero exit code
}
}
protocol A: Hashable {
associatedtype UnitType: Dimension
var units: [UnitType] { get set } // If I replace '{ get set }' to '{ get }', it will compile
}
struct B: A {
var units: [UnitMass] = []
}
如果我删除@State声明,一切都会正常工作。
如果数组包含原始类型,则一切正常
protocol A: Hashable {
var units: [Int] { get set }
}
struct B: A {
var units: [Int] = []
}
struct ContentView: View {
@State var a: any A
var body: some View {
VStack { }
}
func callExample() {
a.unit // Command SwiftCompile failed with a nonzero exit code
}
}
protocol A: Hashable {
associatedtype UnitType: Dimension
var unit: UnitType { get set }
}
struct B: A {
var unit = UnitArea(symbol: "")
}
在解决此问题之前,这里是相关问题中建议的解决方法:
本质上,您必须通过协议扩展手动提供一定程度的间接性。
这样的东西可以很好地编译(在 Swift 5.8.1 上测试):
struct ContentView: View {
@State var a: any A
var body: some View {
Text("\(a.getValue().count)")
}
}
protocol A: Hashable {
associatedtype UnitType: Dimension
var units: [UnitType] { get set } // If I replace '{ get set }' to '{ get }', it will compile
}
struct B: A {
var units: [UnitMass] = []
}
// ----v Added Code
extension A {
func getValue() -> [UnitType] { units }
}