在 “ Swift编程语言” 的“字符串”部分的“字符串 可变性” 小节中,它表示:
您String可以通过将某个变量分配给变量(在这种情况下可以修改)或常量(在这种情况下不能修改)来指示是否可以修改(或 变异 ):
String
并给出示例代码:
var variableString = "Horse" variableString += " and carriage" // variableString is now "Horse and carriage" let constantString = "Highlander" constantString += " and another Highlander" // this reports a compile-time error - a constant string cannot be modified”
这本书中的iBooks 这里,或在Web浏览器在这里。
在下一段中,它声称“字符串是值类型”。
我的问题:对我来说,这看起来像个可变的字符串。看起来就像我在Java(或C#,Python和其他语言)中所惯用的:具有可变变量绑定的不可变字符串对象。换句话说,有一个对象“马”,然后它创建了一个新的字符串对象“马和马车”,并将其设置为相同的变量。而且由于无法分辨不可变对象的引用与值类型之间的区别(对吗?),我想知道:为什么他们这样描述它?这些Swift字符串与其在Java中的方式之间有什么区别吗?(或C#,Python,Objective-C / NSString)
以某种方式,“可变”和“不可变”仅在谈论引用类型时才有意义。如果您尝试将其扩展为值类型,则可以将所有值类型在功能上等同于“不可变”引用类型。
例如,考虑一种var类型Int。这是可变的吗?你们中的某些人肯定会说-您可以通过为其分配(=)来更改其可见的“值” 。然而,同样可以的可以说var的NSNumber和NSString-您可以通过分配给它改变它的可见价值。但是NSNumber和NSString被描述为 不可变的 类。
var
Int
=
NSNumber
NSString
引用类型真正发生的事情是,给它们赋值会导致变量(指针)指向新对象。旧对象或新对象本身都不会“更改”,但是由于它指向另一个对象,因此您“看到”了一个新值。
当我们说一个类是“可变的”时,我们的意思是它提供了一个API(方法或引用)来实际改变对象的内容。但是,我们如何知道对象已更改?(而不是它是一个新对象?)这是因为我们可以对同一对象有另一个引用,并且通过一个引用对对象的更改可以通过另一个引用看到。但是这些属性(指向不同的对象,具有指向同一对象的多个指针)本质上仅适用于引用类型。根据定义,值类型不能具有这样的“共享”(除非“值”的一部分是引用类型,如中的Array),因此,值类型不会发生“可变性”的结果。
Array
因此,如果您制作了一个包装整数的不可变类,则在操作上它等效于Int-在两种情况下,更改变量值的唯一方法是为其分配(=)。因此,Int同样应将其视为“不变的”。
Swift中的值类型稍微复杂一些,因为它们可以具有方法,其中一些可以是mutating。因此,如果可以mutating在值类型上调用方法,则该方法可变吗?但是,如果我们考虑mutating将值类型上的方法称为语法糖来为其分配一个全新的值(无论该方法将其突变为什么),我们都可以克服。
mutating