深入理解Swift中的Class和Struct

栏目: Swift · 发布时间: 6年前

内容简介: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
复制代码

通过上面的代码可以了解到,其实 catblackCat 指向的是同一个Animal的instance。它们只是这个instance的两个不同的名字而已。如下图所示:

深入理解Swift中的Class和Struct

Note

我们看到上述代码把 catblackCat 声明为了 let ,但是我们依然可以修改它的属性,因为 catblackCat 引用的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 。如下图所示:

深入理解Swift中的Class和Struct

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更快

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

A Byte of Python

A Byte of Python

Swaroop C H / Lulu Marketplace / 2008-10-1 / USD 27.98

'A Byte of Python' is a book on programming using the Python language. It serves as a tutorial or guide to the Python language for a beginner audience. If all you know about computers is how to save t......一起来看看 《A Byte of Python》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试