转载

Swift中的结构体与类

在学C++时,老师经常会问的一个问题就是:类和结构体有什么区别啊?

在学操作系统之前,这两者似乎除了一些默认权限上的不同也没有什么太明显的区别。

今天我们来聊聊在Swift中的结构体和类,Swift中的类和结构体的运用有着明显的区别,通过一番探赜,体会到了为什么Swift是一门更安全的语言。

(如下的讨论只针对Swift中的类和结构体,其他语言中不一定完全适用。)

共性与不同

结构体和类有很多共性,在C语言中之所以也可以使用面向对象的编程思想就是因为结构体和函数指针的存在。在Swift中它们之间有如下共性:

  • 都可以定义属性用于存储值
  • 都可以使用下标来提供值访问
  • 都可以定义方法
  • 都可以定义构造器
  • 都可以写extension
  • 都可以实现协议

不过,似乎类的功能更多一些,比如

  • 类可以使用继承
  • 引用计数允许一个类的多次引用
  • 类的实例可以释放其分配的资源
  • 类的实例可以在运行时得知其类型

在OC中, NSStringNSArrayNSDictionary 类型都是类类型,而Swift中的 StringArrayDictionary 都是结构体。

一般来说结构体和枚举都是值类型,而类是引用类型。也就是说,在OC中诸如 NSString 这些类型作为参数被传入时不会发生值拷贝,而是传递现有实例的引用,而在Swift中它们的值会被拷贝。当然Swift的文档中也提到了:Swift在幕后只在绝对必要的情况下才会做出值拷贝。Swift 会管理所有的值拷贝以确保性能最优化,所以没必要回避赋值以保证性能最优化。

可能你会问,为什么要这么做?参考了一下 stackoverflow 里面的讨论。由于struct是值类型,所以有着不可变的特性。而Swift恰恰追求的是线程安全,不可变性极大的有助于线程安全。这也是Swift在方便性与安全性上的一种妥协。

所以,至此也不难理解为什么 Swift官网 中关于Swift Feature的描述中第一条就是 Safe 。简单的来说就是:一时的方便可能会为今后的维护留下隐患。

用途

结构体实例总是通过值传递,类实例总是通过引用传递。这意味两者适用不同的任务。所以如何选择就成为了一个问题。参考了Apple官方的文档以及他人的资料,总结如下:

当符合一条或多条以下条件时,建议使用结构体:

  • 该数据结构用来封装少量简单的数据值。
  • 该数据结构的实例在被传递时,明确的需要使用值传递。
  • 该数据结构中所存储的值类型属性也应该被拷贝而不是引用传递时。
  • 该数据结构不需要继承另一个已有类型的属性。

举例来说,以下情况适合使用结构体:

  • 几何形状,封装 width height 属性。
  • 三位坐标系内的一点,封装 x y z 属性。

除此外,大多数情况下自定义的数据结构的构造都应该是类。

原文  http://iJack.pw/2016/03/02/struct-vs-class-in-swift/
正文到此结束
Loading...