这篇文章不探讨let.或者const的含义与用法,而是要探讨一个概念
value types is immutable
理念上的不可变
值类型是无法改变的。这个如何理解,比如下面的例子
<pre>
struct Person{
var name:String
var age:Int
mutating func setAge(age:Int){
self.age = age
}
}
var person_Lilei = Person(name:"lilei",age:18)
print(person_Lilei.name) //print out lilei
person_Lilei.name = "hanmeimei"
print(person_Lilei.name)//print out hanmeimei
</pre>
what???不是值类型不可改变么?是的值类型不可改变,但是为什么出现这种输出呢。
来看一个例子
<pre>
var a = 4;
a = 10
</pre>
那么是a改变了,还是4改变了?
现在再回头来看看person,是person改变了,还是person所代表的对象改变了。
a/person 均为变量,看看维基百科关于变量的定义
在程序设计中,变数(英语:Variable,scalar)是指一个包含部分已知或未知数值或资讯(即一个值)之储存位址,以及相对应之符号名称(识别字)
可见a没有改变,只是a地址上放的东西变了,以前放的4,现在放的是10了,但是4的概念没有变成10,“4是4,10是10,40是40,14是14....,value types is immutable"。
再来看person,是否可以理解为person里面放的对象变掉了?由person[lilei]的对象,被换成了person[hanmeimei]对象。
name赋值操作之下到底怎么实现了,我不知道。我只是给予一定的猜测:
观察可以知道,每一个struct对象都有一个self属性【这个和C++,OC,Java等有所区别】
setAge method中的self,是person的属性,而不是C++
<pre>
setAge(Perons* this,int age)
</pre>
不是OC 的
<pre>
id objc_msgSend ( id self, SEL op, ... );
</pre>
可以猜测为
<pre>
func setName(name:String){
var copyself =self.copy()
copyself.name = name
self = copyself
}
</pre>
是的,person里所放的对象变掉了。【注意:这只是我个人的猜测,目前为止我还没有找到任何的依据,但这明显符合value types is immutable的概念】
这就看来,person 由person[lilei]变成person[hanmeimei]和a 由 4 变成10 的性质是一样的。
我想了很久,为什么Struct的实例方法默认情况下不可以改变实例的属性,必须要加上关键字mutating才可以改变,而对应的属性声明是var。从如果不加mutaing,引发的错误来看。
不可变的是self,也就是Person 实例本身,更进一步的佐证了我的猜测,可以看出本身Struct的设计上符合了value types is immutable,毕竟Struct 是 value types。
比较直观的不可改变,
当 value types 类型的值在被:赋值,初始化,参数传递的时候,不可改变。
例如:
<pre>
var person_Lili = person_Lilei
perons_Lili.name = "lili"
print(person_Lilei.name) //print out lilei
</pre>
这种情况下不管person_Lili,做任何改变,对于person_Lilei来说都是不可改变的。这也说明了,为什么在多线程环境下,immutable是比较安全的。