在Java中,我们可以使用int ans = (42+45-48-5-15+20)*2;
// Here---^----------------^
关键字使数组引用不可变,并使数组内容可变
final
在Swift中,他们更进一步。使用final int[] array = {1, 2, 3};
// Ok. Array content mutable.
array[0] = 9;
// Compiler error. Array reference immutable.
array = new int[]{4, 5, 6};
关键字,将使数组引用和数组内容不变。
let
在Swift中,可以使数组引用不可变,但数组内容可变吗?
答案 0 :(得分:3)
问题的答案是“是”和“否”,取决于您所拥有的。
如果决定声明一个简单的“ let”常量,则无法对其进行修改。 为什么呢因为它可以防止您产生副作用(并且进行了一些优化)。
例如,如果您只想浏览列表并打印值,则无需修改列表。
myArray = [1,2,3]
for element in myArray {
print(element)
}
为什么会很酷?现在,如果您知道不想修改列表,那么它将阻止您使用可以修改列表的功能。这将节省您的时间,并避免了某些意外行为。
如果您声明var
并且不修改值,Swift也会告诉您。
此外,如果您使用结构或类,则Swift中不可变的概念会很有趣。
想象一下,您具有这种结构和此类:
struct TestStruct {
var myInt: Int
init(myInt: Int) {
self.myInt = myInt
}
}
struct TestClass {
var myInt: Int
init(myInt: Int) {
self.myInt = myInt
}
}
在此结构中,您有myInt
,即var
。如果您尝试用一个let常量声明一个TestStructure
和TestClass
对象,会发生什么?
let testStruct = Test(myInt: 3)
// Cannot assign to property: 'test' is a 'let' constant
test.myInt = 5
let testClass = Test(myInt: 3)
// It works
test.myInt = 5
在结构中,let
会传播到每个字段,而类不是这种情况。
答案 1 :(得分:1)
使用let关键字将使数组引用和数组内容不变。
这是不正确的。这里没有“数组引用”。数组是一个值,就像整数是一个值一样。没有“数组引用”。变量可以是let
或var
,但这不会改变其值的性质。您不会说var n = 4
使“ 4”变了。同样,var ns = [1,2,3]
不会使[1,2,3]
可变。这仅表示您可以更改ns
所指的内容。调用ns.append(5)
就像n += 1
一样。在每种情况下,它们都分配一个新值。他们不会改变旧值。
作为实现和优化的详细信息,用于ns
的基础数组存储可能会被突变并用于新的ns
值。但这对呼叫者是不可见的。例如:
var array = [1,2] {
didSet { print("\(oldValue) -> \(array)") }
}
array.append(1)
array = [1,2,1]
// [1, 2] -> [1, 2, 1]
// [1, 2, 1] -> [1, 2, 1]
追加和分配之间没有深远的区别。他们都是作业。并且请注意,将值设置为相同的值仍然只是一种分配。
我之所以如此,是因为如果您的Java代码依赖于共享的可变状态(程序的一部分修改了数组,而其他部分则应该具有自己的代码),则您不能仅仅通过Java方法进行转换并使其工作参考更新)。但是,如果您的Java以这种方式工作,我建议您改进Java以减少对Java的依赖。只要您通常只传递值和返回值,那么它在Swift中的工作原理与在Java中完全相同。
如果您仍然需要这种可变数组,则可以通过将Array包装在类中来轻松构建一个数组:
final class ArrayRef<Element>: MutableCollection, ExpressibleByArrayLiteral {
private var elements: [Element] = []
init(arrayLiteral elements: Element...) {
self.elements = elements
}
var startIndex: Int { elements.startIndex }
var endIndex: Int { elements.endIndex }
func index(after i: Int) -> Int { elements.index(after: i) }
subscript(position: Int) -> Element {
get { elements[position] }
set { elements[position] = newValue }
}
}
let array: ArrayRef = [1, 2, 3]
// Ok. "Array" content mutable.
array[0] = 9
// Compiler error. "Array" is immutable.
array = [4, 5, 6]
(这是一个非常简单且未经优化的实现。通过进行更多工作,您可以使其更高效并改善界面。)
但是除非您确实需要,否则我不建议您这样做。有一个原因它在stdlib中不存在。