美文网首页
Swift的类和结构体

Swift的类和结构体

作者: 做你的小星星 | 来源:发表于2017-03-31 14:36 被阅读23次

类和结构体对比

Swift中类和结构体有很多共同点。共同点:

  • 定义属性用于存储值
  • 定义方法用于提供功能
  • 定义附属脚本用于访问值
  • 定义构造器用于生成初始化值
  • 通过扩展以增加默认实现的功能
  • 符合协议以对某类提供标准功能

与结构体相比,类还有如下的附加功能:

  • 继承允许一个类继承另一个类的特征
  • 类型转换允许在运行时检查和解释一个类实例的类型
  • 解构器允许一个类实例释放任何其所被分配的资源
  • 引用计数允许对一个类的多次引用

结构体与类的根本区别在于:
结构体是值类型,类是引用类型

值类型和引用类型

  • 值类型(Value Types):每个实例都保留了一分独有的数据拷贝,一般以结构体 (struct)、枚举(enum) 或者元组(tuple)的形式出现。
  • 引用类型(Reference Type):每个实例共享同一份数据来源,一般以类(class)的形式出现。
    通过下面这个例子可以验证结论
// 定义一个结构体
struct testStruct {
    var a: Int
    var b: Int
}
var s = testStruct(a: 1, b: 1) // 初始一个结构体
let s1 = s // 拷贝s
s.a = 10 // 更改s的数据,s1不受影响
print("s = \(s) s1 = \(s1)") // 输出结果:s = testStruct(a: 10, b: 1) s1 = testStruct(a: 1, b: 1)
===
// 定义一个类
class testClass: NSObject {
    var a: Int
    var b: Int
    init(a: Int, b: Int) {
        self.a = a
        self.b = b
    }
    override var description: String {
        return "\(a, b)"
    }
}
var s2 = testClass.init(a: 1, b: 1) //初始化一个类
let s3 = s2 // 拷贝s2
s2.a = 20 // 更改s2的数据,s3受影响
print("s2 = \(s2) s3 = \(s3)") // 输出结果:s2 = (20, 1) s3 = (20, 1)

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

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

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

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

如何选择类型?

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

什么时候该用值类型:

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

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

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

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

相关文章

网友评论

      本文标题:Swift的类和结构体

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