结构体和类

结构体

struct Date {
    var year: Int
    var month: Int
    var day: Int
}
//编辑器自动生成
var date = Date(year: 2019, month: 6, day: 23)

结构体的初始化器


思考:下面代码能编译通过么?

struct Point {
    var x: Int?
    var y: Int?
}
var p1 = Point(x: 10, y: 10)
var p2 = Point(y: 10)
var p3 = Point(x: 10)
var p4 = Point()

自定义初始化器


窥探初始化器的本质

struct Point {
    var x: Int = 0
    var y: Int = 0
}
var p = Point()

struct Point {
    var x: Int
    var y: Int
    init() {
        x=0
        y=0
    }
}
var p = Point()

结构体内存结构

struct Point {
    var x: Int = 0
    var y: Int = 0
    var origin: Bool = false
}
print(MemoryLayout<Point>.size) // 17
print(MemoryLayout<Point>.stride) // 24
print(MemoryLayout<Point>.alignment) // 8


类的初始化器

class Point {
    var x: Int = 10
    var y: Int = 20
}
let p1 = Point()

class Point {
    var x: Int
    var y: Int
    init() {
        x = 10
        y = 20
    }
}
let p1 = Point()
//上面2段代码是完全等效的

结构体与类的本质区别

class Size {
    var width = 1
    var height = 2
}

struct Point {
    var x = 3
    var y = 4
}

func test() {
    var size = Size()
    var point = Point()
}

判断是否在堆空间 汇编查看是否调用alloc malloc


值类型

struct Point {
    var x: Int
    var y: Int
}

func test() {
    var p1 = Point(x: 10, y: 20)
    var p2 = p1
}

p2.x = 11
p2.y = 22
// 请问p1.x和p1.y是多少?

值类型的赋值操作

var s1 = "Jack"
var s2 = s1
s2.append("_Rose")
print(s1) // Jack
print(s2) // Jack_Rose

var a1 = [1, 2, 3]
var a2 = a1
a2.append(4)
a1[0] = 2
print(a1) // [2, 2, 3]
print(a2) // [1, 2, 3, 4]

var d1 = ["max" : 10, "min" : 2]
var d2 = d1
d1["other"] = 7
d2["max"] = 12
print(d1) // ["other": 7, "max": 10, "min": 2]
print(d2) // ["max": 12, "min": 2]
struct Point {
    var x: Int
    var y: Int
}
var p1 = Point(x: 10, y: 20)
p1 = Point(x: 11, y: 22)


引用类型

class Size {
    var width: Int
    var height: Int
    init(width: Int, height: Int) {
        self.width = width
        self.height = height }
}

func test() {
    var s1 = Size(width: 10, height: 20)
    var s2 = s1
}
s2.width = 11
s2.height = 22
// 请问s1.width和s1.height是多少?


对象的堆空间申请过程

class Point  {
    var x = 11
    var test = true
    var y = 22
}
var p = Point()
class_getInstanceSize(type(of: p)) // 40
class_getInstanceSize(Point.self) // 40

引用类型的赋值操作


值类型、引用类型的let

struct Point {
    var x: Int
    var y: Int
}

class Size {
    var width: Int
    var height: Int
    init(width: Int, height: Int) {
        self.width = width
        self.height = height
    }
}


嵌套类型

struct Poker {
    enum Suit : Character {
        case spades = "♠️", hearts = "♥️", diamonds = "♦️",clubs = "♣️"
    }
    enum Rank : Int {
        case two = 2, three, four, five, six, seven, eight, nine, ten
        case jack, queen, king, ace
    }
}

print(Poker.Suit.hearts.rawValue)

var suit = Poker.Suit.spades
suit = .diamonds

var rank = Poker.Rank.five
rank = .king

枚举、结构体、类都可以定义方法

class Size {
    var width = 10
    var height = 10
    func show() {
        print("width=\(width), height=\(height)") }
}
let s = Size()
s.show() // width=10, height=10

enum PokerFace : Character {
    case spades = "♠️", hearts = "♥️", diamonds = "♦️",clubs = "♣️"
    func show() {
        print("face is \(rawValue)")
    }
}
let pf = PokerFace.hearts
pf.show() // face is ♥️

struct Point {
    var x = 10
    var y = 10
    func show() {
        print("x=\(x), y=\(y)")
    }
}
let p = Point()
p.show() // x=10, y=10
Point.show        0x100002320
show1             0x100001e70
全局变量           0x10000bad0
堆空间             0x102908550
局部变量(栈空间)    0x000007ffeefbf400
s
很大一串数字的一般在栈空间
中间不是4个010后跟一大串数字一般在堆空间