Swift 不可变的'var'数组
我想用Swift创建一个数组,它是不可变的,但可以完全替换,采用函数式编程的风格 我知道我可以通过以下方式创建它们:Swift 不可变的'var'数组,swift,immutability,Swift,Immutability,我想用Swift创建一个数组,它是不可变的,但可以完全替换,采用函数式编程的风格 我知道我可以通过以下方式创建它们: var mutable = [1,2,3] // can change reference, add, remove, etc let immutable = [4,5,6] // cannot replace reference or add, remove, etc 我想要不可变的属性,但仍然能够更改变量指向的不可变数组。例如,我希望此操作失败: myArr.appen
var mutable = [1,2,3] // can change reference, add, remove, etc
let immutable = [4,5,6] // cannot replace reference or add, remove, etc
我想要不可变的属性,但仍然能够更改变量指向的不可变数组。例如,我希望此操作失败:
myArr.append(42) // fails. immutable array
但我希望这一切能够成功:
// Desired behavior:
// Multiply each element in the immutable array by 2
// Return a new immutable array, assigned to the old var
immutable = immutable.map { $0 * 2 } // ERROR: can't replace immutable ref
类似,但不是答案:
let
不能使用,因为它在整个运行时都不会更改
我个人更喜欢使用var
并声明NSArray
。您可以重新分配变量以指向另一个不可变的NSArray
,但不能修改NSArray
的内容
陷阱在于,如果您设法将其强制转换为
NSMutableArray
我不知道如何使用内置的数组
类型来实现这一点,则会产生运行时崩溃。
您可以做的是定义一个自定义的ConstantArray
类型
它包含一个数组,并且只有不可变的访问器方法
(全部转发到包含的数组):
对于映射,可以使用全局map()
函数
(或Array
的map()
方法)并将结果转换回ConstantArray
:
myArr = ConstantArray(map(myArr) { $0 * 2 })
myArr = ConstantArray(myArr.array.map { $0 * 2 })
extension ConstantArray {
func map<U>(transform: (T) -> U) -> ConstantArray<U> {
return ConstantArray<U>(elements.map(transform))
}
}
或者为ConstantArray
实现map()
方法:
myArr = ConstantArray(map(myArr) { $0 * 2 })
myArr = ConstantArray(myArr.array.map { $0 * 2 })
extension ConstantArray {
func map<U>(transform: (T) -> U) -> ConstantArray<U> {
return ConstantArray<U>(elements.map(transform))
}
}
同样,其他方法,如filter()
和sorted()
可以为
ConstantArray
实现您想要的对数组
没有意义,因为它是一种具有值语义的值类型。变量的值就是数组——所以改变变量的能力和改变数组的能力在某种程度上是一样的
在语义上,以下各项之间没有区别:
myArr.append(42)
还有一些类似(虚构的):
在某种程度上,您可以想象对值类型变量的任何“修改”都可以实现为为变量分配一个全新的值。(可能不是这样做的,因为这样做效率很低,但从语义的角度来看,没有理由不能以这种方式实现。)
“可变性”的概念仅适用于引用类型,其中变量是指向实际对象的引用,并且实际对象可以在多个引用之间共享(因此通过一个引用的“变异”可以通过另一个引用看到)
对于引用类型,您可以根据需要执行任何操作,例如使用不可变的
不可变数组
类,然后如果您有不可变数组
类型的var
变量,则您可以构造一个全新的不可变数组,并将该变量更改为指向新数组,但无法创建任何特定的数组对象从共享引用中看到的“已更改”。对分配给可变变量的不可变NSArray执行进一步操作返回不可变NSArrays?例如:var arr=NSArray(1,2,3);arr=arr.map{$0*2}
。arr现在是可变的还是不可变的?哦,这很聪明。函数库一定是在swift中实现的。这是最干净的swift解决方案,但我非常讨厌它。我们又回到了Java的集合。不可修改列表
。这是一个非常好的观点。我没有考虑数组(和字典)是swift中的一种值类型。实现了我在这个问题上的目标,即能够相信我的函数正在处理的集合不会在我背后发生变异。
myArr.append(42)
myArr = myArr.newArrayWithAppending(42)