【问题标题】:Mutating a struct in its subscript getter在其下标 getter 中改变结构
【发布时间】:2026-02-11 18:25:03
【问题描述】:

在玩结构体时,我发现了以下内容:

struct SomeStruct {
    private(set) var uncount: Int
    subscript(i: Int) -> Int {
        uncount = i  // <--'self' is immutable-----
        return 3
    }
}

let someStructInstance = SomeStruct(uncount: 3)
someStructInstance[345]

上面的代码没有编译通过,因为'self is immutable',不能在下标加上mutating关键字。

但是,以下操作完美:

struct SomeStruct {
    private(set) var uncount: Int
    subscript(i: Int) -> Int {
        get {
            return 3
        }
        set {
            uncount = i  //<--works well now---
        }
    }
}

let someStructInstance = SomeStruct(uncount: 3)
someStructInstance[345]

问题:当两个下标函数都改变结构属性时,为什么一个起作用,而另一个不起作用?

【问题讨论】:

    标签: swift struct syntax


    【解决方案1】:

    你的

    subscript(i: Int) -> Int {
        uncount = i  // <--'self' is immutable-----
        return 3
    }
    

    只定义了一个下标getter,,默认情况下是non-mutating

    如果你真的需要改变 getter 中的属性,那么 你可以声明为mutating get:

    subscript(i: Int) -> Int {
        mutating get {
            uncount = i
            return 3
        }
    }
    

    因此,getter 不能与常量值一起使用 没有了,

    let someStructInstance = SomeStruct(uncount: 3)
    print(someStructInstance[345])
    // error: Cannot use mutating getter on immutable value: 'someStructInstance' is a 'let'
    

    它必须是一个变量:

    var someStructInstance = SomeStruct(uncount: 3)
    print(someStructInstance[345])     // 3
    print(someStructInstance.uncount)  // 345
    

    【讨论】:

    • 有副作用的吸气剂... :/