首先,我有一个协议(protocol),仅定义了几个只读属性,例如:
protocol Example {
var var1:String { get }
var varArray:[String] { get }
}
然后,我想创建一个符合该协议(protocol)的结构。我遇到的问题是,我有两个相互矛盾的要求:
我似乎找不到解决办法。我最接近的是这样的:
struct AStruct : Example {
private lazy var data:(var1:String, varArray:[String]) = {
var stringValue:String = ""
var stringArray:[String] = []
//Generate data
return (stringValue, stringArray)
}()
var var1:String {
return self.data.var1
}
var varArray:[String] {
return self.data.varArray
}
}
问题是,我得到了错误:
Immutable value of type 'AStruct' only has mutating members named 'data'
。有人知道我可以实现目标的方式吗?从技术上讲,
data
变量是可变的,但永远不会更改。我不能将let
与lazy
一起使用,因此无法指定该值一旦生成就永远不会更改。我需要生成值,因为该结构是在主线程上创建的,但是这些值将由另一个进程在后台线程上生成。更新
因此,向我指出,我可以在协议(protocol)和结构中都将getters设置为
mutating
。那行得通,除了我现在有一个问题,就是我不能在其他任何结构中使用这个结构(我是)。因此,最后,我将问题推到了另一个结构中,我不希望该结构是易变的。前任:
struct Container {
let astruct:AStruct
let callback:() -> ()
}
我无法从
AStruct
访问Container
中的变量,因为Container
是不可变的,并且AStruct
的成员变量正在变异。尝试访问它们会给我与我之前提到的相同的错误消息。将容器更改为使用
var
而不是let
会产生相同的错误:struct Container {
var astruct:AStruct
let callback:() -> ()
}
如果我在处理类中设置了一个函数,该函数接收一个
Container
进行处理:func processContainer(cont:Container){
self.doSomething(cont.astruct.var1)
}
我收到相同的错误:
Immutable value of type 'AStruct' only has mutating members names 'sql'
。 最佳答案
由于访问懒惰的data
变量会使AStruct
发生变化,因此对它的任何访问都必须标记为也使该结构发生变化。所以你需要写:
struct AStruct : Example {
// ...
var var1: String {
// must declare get explicitly, and make it mutating:
mutating get {
// act of looking at data mutates AStruct (by possibly initializing data)
return self.data.var1
}
}
var varArray:[String] {
mutating get {
return self.data.varArray
}
}
}
但是,您现在会发现Swift提示您不符合
Example
,因为它的get var1
没有被标记为变异。因此,您必须对其进行更改以匹配:protocol Example {
var var1:String { mutating get }
var varArray:[String] { mutating get }
}