You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

当前Swift中该计算属性能否正确实现类指针的预期功能?

Swift计算属性访问结构体数组的行为验证

现有代码实现

单例类 hugestuff

class hugestuff {
    var dataSources: [String: ThingWithIncrediblyLargeArrays]
    var currentThing: String
}

结构体 ThingWithIncrediblyLargeArrays

struct ThingWithIncrediblyLargeArrays {
    var rawUnsorted: [[String]]
    var liveSorted: [[String]]
    var swapValues: [[String]]
}

简化访问的计算属性

var hot: ThingWithIncrediblyLargeArrays {
    get { dataSources[currentThing]! } // 原代码未处理可选值,此处补全强制解包逻辑
    set { dataSources[currentThing] = newValue }
}

问题验证与分析

结合Swift值类型特性与**写时复制(COW)**机制,对两个问题逐一验证:

(A) 读取数组元素是否会无意义复制数组

执行 x = hugestuff.hot.rawUnsorted[13](修正原问题笔误的enormousArray)时:

  • 计算属性hot的get方法会从dataSources字典中取出对应currentThing的结构体,生成一份结构体副本。但结构体仅包含三个数组的引用,复制开销极小,不会复制数组的底层存储。
  • 访问数组元素属于读取操作,Swift数组的COW机制会保证仅持有原数组的引用,不会触发底层存储的复制。

结论:不存在无意义的数组复制,仅会产生开销可忽略的结构体副本。

(B) 修改结构体属性是否能同步到原数据源

执行 hugestuff.hot.liveSorted = ...(修正原问题笔误的searchRows)时:

  • 计算属性hot的get方法返回的是结构体的临时副本,直接修改该副本的属性只会改变副本内容,不会触发计算属性的set方法。
  • 临时副本在语句执行结束后会被销毁,原dataSources中的结构体不会被修改。

结论:无法直接修改原数据源的结构体属性,必须先获取副本修改后再赋值回hot,才能触发set更新原数据,示例代码如下:

var temp = hugestuff.hot
temp.liveSorted = newSortedArray
hugestuff.hot = temp

优化建议:处理键不存在的情况

可在计算属性的get方法中添加默认值,避免因currentThing不存在于dataSources中导致的崩溃:

var hot: ThingWithIncrediblyLargeArrays {
    get {
        dataSources[currentThing] ?? ThingWithIncrediblyLargeArrays(
            rawUnsorted: [],
            liveSorted: [],
            swapValues: []
        )
    }
    set {
        dataSources[currentThing] = newValue
    }
}

内容的提问来源于stack exchange,提问作者Fattie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 08:06:02