内容简介:Class和Struct是Swift中很重要的两种数据结构,同时也是Swift面试题必问的一道题。所以对Class和Struct理解透彻对我们学习Swift有很大的帮助。当值传递的时候,它是传递对已有instance的引用。下面用代码来解释一下这句话:通过上面的代码可以了解到,其实
Class和Struct是Swift中很重要的两种数据结构,同时也是Swift面试题必问的一道题。所以对Class和Struct理解透彻对我们学习Swift有很大的帮助。
理解Class
Class的定义和使用
class Animal { var name: String? var weight = 0.0 } let cat = Animal() cat.name = "cat" cat.weight = 10 print("cat's name: \(cat.name!), cat's weight: \(cat.weight)") //cat's name: cat, cat's weight: 10.0 复制代码
Class是引用类型
当值传递的时候,它是传递对已有instance的引用。下面用代码来解释一下这句话:
let cat = Animal() cat.name = "cat" cat.weight = 10 let blackCat = cat blackCat.name = "blackCat" print("cat's name: \(cat.name!)") // cat's name: blackCat 复制代码
通过上面的代码可以了解到,其实 cat
和 blackCat
指向的是同一个Animal的instance。它们只是这个instance的两个不同的名字而已。如下图所示:
Note
我们看到上述代码把 cat
和 blackCat
声明为了 let
,但是我们依然可以修改它的属性,因为 cat
和 blackCat
引用的instance并没有改变,它们还是引用之前instance,我们只是修改的instance的属性。但是不能将 cat
或者 blackCat
指向另一个实例,如 blackCat = Animal()
会提示 Cannot assign to value: 'blackCat' is a 'let' constant
的错误。
Identity Operators
Swift 提供 ===
和 !==
来判断两个变量或者常量是不是引用同一个instance(只用于class,想一想为什么struct不需要).
if blackCat === cat { print("Identical") //Identical } else { print("Not identical") } 复制代码
===
和 ==
是不一样的。
=== == ==
class Animal { var name: String? var weight = 0.0 } extension Animal: Equatable { static func == (lhs: Animal, rhs: Animal) -> Bool { return lhs.name == rhs.name && lhs.weight == rhs.weight } } let cat = Animal() cat.name = "cat" cat.weight = 10 let blackCat = cat blackCat.name = "catName" let whiteCat = Animal() whiteCat.name = "catName" whiteCat.weight = 10.0 if blackCat === cat { print("Identical") //Identical } else { print("Not identical") } if whiteCat === blackCat { print("Identical") } else { print("Not identical") //Not identical } if whiteCat == blackCat { print("Equal") } else { print("Not Equal") //Equal } 复制代码
理解Struct
Struct的定义和使用
struct FPoint { var x = 0.0 var y = 0.0 //当在struct修改属性的时候需要使用mutating mutating func addX(add: Double) { self.x = self.x + add } } let p1 = FPoint() print("p1's x : \(p1.x), p1's y: \(p1.y)") // p1's x : 0.0, p1's y: 0.0 复制代码
Struct是值类型
当值进行传递的时候,它会copy传递的值。下面用代码来解释一下这句话:
var p2 = p1 p2.x = 3.0 print("p1's x : \(p1.x), p1's y: \(p1.y); p2's x : \(p2.x), p2's y: \(p2.y)") //p1's x : 1.0, p1's y: 2.0; p2's x : 3.0, p2's y: 2.0 复制代码
通过上述代码我们可以看到,将 p1
赋值给 p2
之后改变 p2
的值并不会影响 p1
的值,这是因为在将 p1
赋值给 p2
的时候是拷贝一个instance 值与p1相同
,然后将拷贝的instance赋值给 p2
。如下图所示:
Note
如果struct的instance声明为let,是不能改变instance的值的。如
let p1 = FPoint(x: 1.0, y: 2.0) p1.x = 10.0 //报错:Cannot assign to property: 'p1' is a 'let' constant 复制代码
在项目中如何选择Struct和Class
- 默认使用struct
- 当你需要继承Objective-C某些类的的时候使用class
- 当你需要控制唯一性时使用class
- 使用struct和protocol来实现model继承和共享行为,如下代码所示:
protocol AnimalCommonProtocol { var name: String? { get set } var weight: Double { get set } func run() } struct Cat : AnimalCommonProtocol { func run() { print("cat run") } var name: String? var weight: Double var gender: String? } struct Dog : AnimalCommonProtocol { func run() { print("dog run") } var name: String? var weight: Double var type: String? } 复制代码
总结起来就是一句话:能使用struct就不要使用class
为什么优选struct
- 使用struct不需要考虑内存泄漏和多线程读写的问题,因为在传递值的时候它会进行值的copy
- struct存储在stack中,class存储在heap中,struct更快
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 【1】JavaScript 基础深入——数据类型深入理解与总结
- 深入理解java虚拟机(1) -- 理解HotSpot内存区域
- 深入理解 HTTPS
- 深入理解 HTTPS
- 深入理解 SecurityConfigurer
- 深入理解 HTTP 协议
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
程序员2005精华本
《程序员》杂志社 / 电子工业 / 2006-1 / 45.00元
本书为集结了《程序员》杂志与《msdn开发精选》杂志精华。分上、下两册,内容包括人物&报道、管理与实践、程序员手册、年鉴、《程序员》技术专题、《msdn开发精选》文章精选等。一起来看看 《程序员2005精华本》 这本书的介绍吧!