Swift:Deep in immutable

作者: inclee | 来源:发表于2016-12-03 22:07 被阅读8次

这篇文章不探讨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,引发的错误来看。

error.png

不可变的是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是比较安全的。

相关文章

网友评论

    本文标题:Swift:Deep in immutable

    本文链接:https://www.haomeiwen.com/subject/yygcmttx.html