繁体   English   中英

使用let变异变量

[英]Using let on mutating variable

我有一个简单的自定义类,为简单起见,在示例中可以说它包含单个属性,该属性是字符串数组的数组。 它只有一个方法,可以将第一个对象从一个数组移动到另一个数组。 忽略缺少的初始化程序,这是我编写的现有类的截断版本。

class MyClass: NSObject
{
    var strings:Array< Array< String > >

    func makeMove(fromArray:Int, toArray:Int)
    {
        var from = strings[fromArray] as Array< String >
        var to = strings[toArray]

        let top = from[0]
        to.append(top)
        from.removeAtIndex(0)

        towers[fromTower] = from
        towers[toTower] = to
    }
}

如果我声明MyClass的新实例并对其调用此方法,则会收到编译器警告,指出该实例从未修改过,应将其设为let而不是var

var myInstance = MyClass()    //Warning
myInstance.makeMove(0, toArray:1)


let myInstance = MyClass()    //No warning
myInstance.makeMove(0, toArray:1)

有趣的是,即使在第二个实例中它是一个let ,它应该是一个常量,但实际上在makeMove时该实例确实会发生突变。

在这种情况下怎么了? 我应该使用let还是编译器没有正确识别出它是一个变异函数?

首先,请确保您了解引用类型与值类型。

https://developer.apple.com/swift/blog/?id=10

let关键字可以防止后者,而不是前者的突变。 认为一个的let参考变量为:基准(存储器地址),该变量是指不能改变,但是存储器的内容物。

因此,警告试图告诉您您永远不要将引用myInstance分配给另一个对象,但是您的声明允许这种可能性。

如果您的设计使myInstance始终引用最初分配给它的对象,则让编译器将其表示为let帮助您。 然后随意传递参考,并使用参考的任何副本根据需要更改对象的内容。

总结一下,这是我想根据wjl的建议执行的操作

class MyClass {
    var strings : [[String]] = []

    func makeMove(fromArray from: Int, toArray to: Int) {
        let item = strings[from].removeAtIndex(0)
        strings[to].append(item)
    }
}

let a = MyClass()
a.strings = [["Hi", "H", "A", "C"], ["He", "Ab", "To", "Hehe"]]
a.makeMove(fromArray: 0, toArray: 1)
a.strings           // [["H", "A", "C"], ["He", "Ab", "To", "Hehe", "Hi"]]

// a = MyClass()    // error: cannot assign to value: 'a' is a 'let' constant

您仍然可以更改该对象的实例,但是您不能更改该对象, a指向

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM