Swift里的值类型与引用类型区别和使用

Swift里面的类型分为两种:

●值类型(Value Types):每个实例都保留了一分独有的数据拷贝,一般以结构体 (struct)、枚举(enum) 或者元组(tuple)的形式出现。
●引用类型(Reference Type):每个实例共享同一份数据来源,一般以类(class)的形式出现。

在这篇博文里面,我们会介绍两种类型各自的优点,以及应该怎么选择使用。

值类型与引用类型的区别

值类型和引用类型最基本的分别在复制之后的结果。当一个值类型被复制的时候,相当于创造了一个完全独立的实例,这个实例保有属于自己的独有数据,数据不会受到其他实例的数据变化影响:

代码如下:

// 下面是一个值类型的例子
    struct S { var data: Int = -1 }
    var a = S()
    var b = a                           // b是a的拷贝
    a.data = 42                         // 更改a的数据,b的不受影响
    println("\(a.data), \(b.data)")     // 输出结果 "42, -1"

值类型就好像身份证复印件一样,复印出来之后,修改原件上面的内容,复印件上的内容不会变。

另一方面,复制一个引用类型的时候,实际上是默默地创造了一个共享的实例分身,两者是共用一套数据。因此修改其中任何一个实例的数据,也会影响到另外那个。

代码如下:

// 下面是一个引用类型的例子
    class C { var data: Int = -1 }
    var x = C()
    var y = x                           // y是x的拷贝
    x.data = 42                         // 更改x的数据,等于同时修改了y
    println("\(x.data), \(y.data)")     // 输出结果 "42, 42"

Mutation(修改)在安全中扮演的角色

值类型较引用类型来说,会让你更容易在大量代码中理清状况。如果你总是得到一个独立的拷贝出来的实例,你就可以放心它不会被你app里面的其他部分代码默默地修改。这在多线程的环境里面是尤为重要的,因为另外一个线程可能会在暗地里修改你的数据。因此可能会造成严重的程序错误,这在调试过程中非常难以排除。

由于差别主要在于修改数据的后果,那么当实例的数据只读,不存在需要更改的情况下,用哪种类型都是没有分别的。

你可能在想,有的时候我可能也需要一个完全不变的类。这样使用Cocoa NSObject对象的时候会比较容易,又可以保留值语义的好处。在今天,你可以通过只使用不可变的存储属性,和避开任何可以修改状态的API,用Swift写出一个不可变类(immutable class)。实际上,很多基本的Cocoa类,例如NSURL,都是设计成不可变类的。然而,Swift语言目前只强制struct和enum这种值类型的不可变性,对类这种引用类型则没有。(例如还不支持强制将子类的限制为不可变类)

如何选择类型?

所以当我们想要建立一个新的类型的时候,怎么决定用值类型还是引用类型呢?当你使用Cocoa框架的时候,很多API都要通过NSObject的子类使用,所以这时候必须要用到引用类型class。在其他情况下,有下面几个准则:

什么时候该用值类型:

●要用==运算符来比较实例的数据时
●你希望那个实例的拷贝能保持独立的状态时
●数据会被多个线程使用时

什么时候该用引用类型(class):

●要用==运算符来比较实例身份的时候
●你希望有创建一个共享的、可变对象的时候

在Swift里面,数组(Array)、字符串(String)、字典(Dictionary)都属于值类型。它们就像C语言里面简单的int值,是一个个独立的数据个体。你不需要花任何功夫来防范其他代码在暗地里修改它们。更重要的是,你可以在线程之间安全的传递变量,而不需要特地去同步。在Swift高安全性的精神下,这个模式会帮助你用Swift写出更可控的代码。

(0)

相关推荐

  • Swift编程中用以管理内存的自动引用计数详解

    Swift 内存管理功能是通过使用自动引用计数(ARC)来处理.ARC用于初始化和取消初始化所述系统资源,从而释放使用的类实例的存储器空间当实例不再需要.ARC跟踪代码的实例有效地管理存储资源之间的关系的信息. ARC的功能 在每一次一个新的类实例被创建时ARC分配一块内存以存储信息 init() 关于实例类型和其值的信息存储在存储器中 当类实例不再需要它自动由 deinit() 释放,用于进一步类实例的存储和检索的存储空间 ARC保存在磁道当前参照类实例的属性,常量和变量,使得 deinit(

  • 实例讲解Swift中引用类型的ARC自动引用计数

    一.引言 ARC(自动引用计数)是Objective-C和Swift中用于解决内存管理问题的方案.在学习Objective-C编程时经常会学习到一个关于ARC的例子:在一个公用的图书馆中,每次进入一人就将卡插入,走的时候将自己的卡拔出拿走.图书馆系统会判定只要有卡插入,就将图书馆的灯打开,当所有卡都被取走后,将图书馆的灯关掉.这个例子对应于Objective-C中的对象声明周期管理十分贴切.每当一个对象增加一个引用时,其引用计数会加1,当一个引用被取消时,对象的引用计数减1,当引用计数减为0时,

  • Swift里的值类型与引用类型区别和使用

    Swift里面的类型分为两种: ●值类型(Value Types):每个实例都保留了一分独有的数据拷贝,一般以结构体 (struct).枚举(enum) 或者元组(tuple)的形式出现. ●引用类型(Reference Type):每个实例共享同一份数据来源,一般以类(class)的形式出现. 在这篇博文里面,我们会介绍两种类型各自的优点,以及应该怎么选择使用. 值类型与引用类型的区别 值类型和引用类型最基本的分别在复制之后的结果.当一个值类型被复制的时候,相当于创造了一个完全独立的实例,这个

  • js中值类型和引用类型的区别介绍

    1.JavaScript中的变量类型有哪些? (1)值类型(基本类型):字符串(string).数值(number).布尔值(boolean).undefined.null  .symbol (2)引用类型:对象(Object).数组(Array).函数(Function) 2.值类型和引用类型的区别 (1)值类型: 1.占用空间固定,保存在栈中(当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁了.因

  • C#基础入门之值类型和引用类型的区别详析

    目录 一.值类型和引用类型的区别 1.赋值时的区别 2.内存分配的区别 3.来自继承结构的区别 二.总结 一.值类型和引用类型的区别 .NET的类型可以分为两类:值类型和引用类型.这两种类型各有特点,即使它们都继承自System.Object,并且有装箱和拆箱等操作确保两种类型可以方便地交互,但是理解值类型和引用类型将有助于程序员编写出高效的代码,相反的,在不理解值类型和引用类型的情况下,程序员很容易编写出可以正确执行但性能较差的代码. 所有.NET的类型都可以分为两类:值类型和引用类型.最简单

  • C#中值类型和引用类型的区别深度分析

    本文通俗易懂的分析了C#中值类型和引用类型的区别.分享给大家供大家参考.具体分析如下: 似乎"值类型和引用类型的区别"是今年面试的流行趋势,我已然是连续三次(目前总共也就三次)面试第一个问题就遇到这个了,这是多大的概率啊,100%,哈哈,我该买彩票去! 言归正传,咱还是先来探讨探讨这二者之间有什么区别吧.记得有一次电话面试中,我直接跟面试官说:"值类型是现金,引用类型是存折",后来想想当时说这话虽是有点儿冲动地脱口而出,但也没什么不妥.我这人不善于背理论的教条,喜欢

  • JavaScript中值类型和引用类型的区别

    JavaScript的数据类型分为两类:原始类型和对象类型.其中,原始类型包括:数字.字符串和布尔值.此外,JavaScript中还有两个特殊的原始值:null和undefined,它们既不是数字也不是字符串,更不是布尔值.它们通常分别代表了各自特殊类型的唯一成员.JavaScript中除了数字.字符串.布尔值.null和undefined之外的就是对象了. JavaScript中值类型和引用类型的区别 JavaScript中的值类型的值是不可变的: 任何方法都无法改变值类型的值.数字.布尔值.

  • JAVA中值类型和引用类型的区别

     1. Java中值类型和引用类型的不同? [定义] 引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值, 那么调用这个方法是传入的变量的值也将改变.值类型表示复制一个当前变量传给方法, 当你在这个方法中改变这个变量的值时,最初生命的变量的值不会变.通俗说法: 值类型就是现金,要用直接用:引用类型是存折,要用还得先去银行取现.----(摘自网上) [值类型] 也就是基本数据类型 基本数据类型常被称为四类八种 四类:  1,整型 2,浮点型 3

  • C#中值类型和引用类型的区别

    一.值类型和引用类型的区别 .NET的类型可以分为两类:值类型和引用类型.这两种类型各有特点,即使它们都继承自System.Object,并且有装箱和拆箱等操作确保两种类型可以方便地交互,但是理解值类型和引用类型将有助于程序员编写出高效的代码,相反的,在不理解值类型和引用类型的情况下,程序员很容易编写出可以正确执行但性能较差的代码. 所有.NET的类型都可以分为两类:值类型和引用类型.最简单也最明确的一个区分标准是:所有的值类型都继承自System.ValueType(System.ValueT

  • C#值类型和引用类型的深入理解

    从概念上看,值类型直接存储其值,而引用类型存储对其值的引用.这两种类型存储在内存的不同地方.在C#中,我们必须在设计类型的时候就决定类型实例的行为.这种决定非常重要,用<CLR via C#>作者Jeffrey Richter的话来 说,"不理解引用类型和值类型区别的程序员将会给代码引入诡异的bug和性能问题(I believe that a developer who misunderstands the difference between reference types and

  • 一看就懂:图解C#中的值类型、引用类型、栈、堆、ref、out

    C# 的类型系统可分为两种类型,一是值类型,一是引用类型,这个每个C#程序员都了解.还有托管堆,栈,ref,out等等概念也是每个C#程序员都会接触到的概念,也是C#程序员面试经常考到的知识,随便搜搜也有无数的文章讲解相关的概念,貌似没写一篇值类型,引用类型相关博客的不是好的C#程序员.我也凑个热闹,试图彻底讲明白相关的概念. 程序执行的原理 要彻底搞明白那一堆概念及其它们之间的关系似乎并不是一件容易的事,这是因为大部分C#程序员并不了解托管堆(简称"堆")和线程栈(简称"栈

  • C#值类型、引用类型、泛型、集合、调用函数的表达式树实践

    目录 一,定义变量 二,访问变量/类型的属性字段和方法 1. 访问属性 调用静态类型属性 调用实例属性/字段 2. 调用函数 调用静态类型的函数 调用实例的函数 三,实例化引用类型 new 给属性赋值 创建引用类型 示例 四,实例化泛型类型于调用 五,定义集合变量.初始化.添加元素 一,定义变量 C# 表达式树中,定义一个变量,使用 ParameterExpression. 创建变量结点的方法有两种, Expression.Parameter() Expression.Variable() //

随机推荐