值类型和引用类型

  • [值类型和引用类型]
    • [什么是值类型(value type)和引用类型(reference type)]
    • [两者有什么不同]
    • [请在保证安全的情况下修改变量值]
    • [如何选择]
    • [c++类型行为的不一致性]
    • [ 参考文章]

变量类型可以帮助开发者理清程序的数据流,以写出更健壮的代码。本文通过对swift语言中的两种变量类型的介绍,来说明哪些情况下适合使用value/reference type。阅读本文不需要对swift有深入了解,当然熟悉swift编程对理解本文会有帮助。

什么是值类型(value type)和引用类型(reference type)

在swift中,一个类型要么是value type, 要么是reference type。value type指每一个变量在内存中都有单独的一份数据拷贝。reference type指数据在内存中只有一份拷贝,多个变量共享它的值。和c++中类型的使用方式不同,swift中类型的属性(value/reference)是由类型本身决定的,作为语言标准给出,稍后本文会再做介绍。

比如c++中,

#include <iostream>
int main() {
    int a = 1;
    int &b = a;    //c++中的引用可以使用在所有的类型上
    b = 2;
    printf("a = %d, b = %d\n", a, b);    //输出结果为:a = 2, b = 2
}

两者有什么不同

辨别value type,最基本和最有效的方法是观察它的拷贝行为--赋值、初始化、参数传递等带来的影响,即通过内存数据拷贝 创建 一个独立的实例(instance)。

// Value type example
struct S { var data: Int = -1 }
var a = S()
var b = a                        // a is copied to b
a.data = 42                        // Changes a, not b
println("\(a.data), \(b.data)")    // prints "42, -1"

拷贝引用则不同,它的行为类似于创建了一个指针,原来在内存中的数据依然保持一份拷贝。因而改变其中某一个变量的值也会影响其他变量,即产生副作用。

// Reference type example
class C { var data: Int = -1 }
var x = C()                      // 建立一个对象的引用x
var y = x                        // 建立对象的另一个引用y
x.data = 42                        // changes the instance referred to by x (and y)
println("\(x.data), \(y.data)")    // prints "42, 42"

可以看出这个例子和之前c++引用产生了同样的效果。

请在保证安全的情况下修改变量值

开发软件,其中最重要的要求(之一)是程序的正确性,一种保证是来自于编程语言本身,另一种当然是来自程序员。那么程序员在写代码的过程中如何选择使用的类型呢?value type和reference type相比较,选择使用value type可以使你的程序直观上更加符合逻辑。如果所有的变量在内存中都有自己单独的一块区域,你就大可不必担心程序的其他部分在无意中修改这些变量的值。这在多线程环境中尤其重要,因为不同的线程会同时修改变量的值。如果变量是reference类型就十分危险,这使你的程序出现不可预期的结果,调试起来也非常困难。

更理想的一种情况是,你声明和使用的变量是只读(不可写)的,就不会出现数据不一致的情况发生。实际上,在没有变量值改动的程序中,变量是type的或者reference的对程序的行为没有任何影响。这时候reference内存占用少,当然是优先使用reference。

如何选择

使用value type,当:

  • 你想要变量之间的赋值隐含数据拷贝,使变量之间的状态完全独立。
  • 代码中的数据操作分布在多个进程。

使用reference type,当:

  • 创建共享和允许修改的状态。

很多人其实有一种对编程语言的误解,认为在语言层面约束越少的语言越好,这样就可以很容易实现想要的功能。但是灵活性带来的坏处更加容易被人忽视。交给程序员处理的事情越多,导致写出来的代码更加容易产生bug,代码可阅读性大大降低,同时增加重构的难度。

而swift在这方面给出了比较严格的限制,在swift中,struct, Array, String, 和 Dictionary 都是value type,它们的行为就像c语言中的int,你几乎不用做任何额外的工作,比如为了防止代码的其余部分对数据进行修改而显式地为变量分配额外的内存空间,这些繁琐的过程都会因为swift中变量的value type的属性,而交给编译器去做。更加重要的是,你可以很放心的将变量的数据拷贝交给其他进程进行操作而不用担心同步问题。这些语言层面的约束都是为了程序员可以写出可预测的代码。作为对比,下文介绍c++是怎么做的。

c++类型行为的不一致性

碰巧在微信中看到的一篇文章:C++ 之 stl::string 写时拷贝导致的问题。c++在语言标准上允许不同的数据拷贝机制,联系到本文的概念,即c++中的类型是value type还是reference type取决于编译器的实现。当语言标准容忍实现的灵活性时,虽然多数时候是为了优化性能,但是带来的问题似乎更加严重--导致程序的运行结果不同于预期。

参考文章

  1. Value and Reference Types
  2. Why java has "String" type and not "string"? - Stack Overflow
  3. If immutable objects are good, why do people keep creating mutable objects?
  4. C++之stl::string写时拷贝导致的问题
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容