[英]Swift Struct with Lazy, private property conforming to Protocol
首先,我有一個協議,只定義了一些readonly屬性,例如:
protocol Example {
var var1:String { get }
var varArray:[String] { get }
}
然后我想創建一個符合該協議的結構。 我遇到的問題是,我有兩個相互矛盾的要求:
我似乎找不到辦法做到這一點。 我最接近的是這樣的:
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
,所以我不能指定一旦它被創造的價值永遠不會改變。 我需要生成值,因為struct是在主線程上創建的,但是值將由后一個進程完全在后台線程上生成。
所以有人向我指出,我可以讓getter在協議和結構中都發生mutating
。 這是有效的,除了我現在有一個問題,我不能在任何其他結構(我是)中使用此結構。 所以最后,我把問題推到另一個結構中,我不想讓它變成可變的。
例如:
struct Container {
let astruct:AStruct
let callback:() -> ()
}
我無法從Container
訪問AStruct
的變量,因為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 }
}
所以我想詳細說明我最終遵循的解決方案。 事實證明,我認為Swift目前無法實現我的目標。 一旦你開始mutating get
道路,它最終會級聯到太多區域(所有容器結構都需要變異等)。 最后,這種破壞了我想首先使用結構的全部原因。
也許在未來的道路上Apple會添加一個lazy let var = ...
這將通過保證延遲變量只設置一次來確保不變性......只是不立即。
所以我的解決方案只是完全放棄structs
並使用classes
來代替。 我保持類在功能上不可變,所以我仍然保留它。 從字面上看,我所要做的就是將struct
更改為class
,現在懶惰的構造工作完美,我的所有問題都消失了......除了我正在使用類。
總而言之,@ AirspeedVelocity有一個正確的解決方案,即使我的需求難以為繼,所以我會接受他的解決方案。 我剛剛離開這里,所以其他人可以理解我是如何克服這個問題的...使用類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.