Swift 关键词 -- struct/enum/mutating

struct

struct 值引用

在swift中,类型引用和值引用的区别在于,对于类型引用(class reference),将变量a赋值给变量b,即b = a,这样的赋值语句仅仅将b的指针与a的指针一样,指向同一块内存区域,此时改变b的值,a也会跟着改变;而对于值引用(value reference),赋值语句b = a处理的过程是开辟一个新的内存b,将a变量的内容拷贝后存放到内存b,这时a和b完全没有关系的两个变量,对b的改变不会影响到a,反之亦然。

// struct value reference, class reference

func valueCopyValid() -> Void {
    var personXm = Person(name: "xiao-min", age: 6, sex: .man)
    var personXmCopy = personXm
    personXmCopy.age = 20
    print("\(personXm) : \(personXmCopy)")
}

print:
Person(name: "xiao-min", age: 6, sex: swift_learn_keyword.Sex.man) 
Person(name: "xiao-min", age: 20, sex: swift_learn_keyword.Sex.man)

struct和class的主要区别,

  1. struct是值引用,而class是类型引用
  2. struct没有继承的功能,class有继承功能
    struct和class这两个基本层面的区别,体现了区别于Objective-C语言,swift语言带来了全新的天翻地覆的改变。

首先说第一点区别,从swift的更新和struct不断完善来看,苹果公司更加推荐使用struct来代替class,因为struct值引用和class类型引用这点区别,保证使用struct编码能写出更加安全可靠的代码。为什么这样说呢,class类型引用在赋值时是将变量指向了同一块内存地址,这在一个长时间的跨度上会带来一些意想不到的问题,试想一个简单的例子,viewControllerA持有一个NSMutableArray数组mutalbeArray,它包含100条user信息,此时将mutableArray赋值给viewControllerB,对于viewControllerB而言,它仅仅需要前10条user信息,所以它将mutableArray多余的信息删除了,这样一个脑残的操作导致了viewControllerA模块展示错误和潜在的逻辑错误。而使用struct值引用则不会出现这样的问题。

第二点区别,struct没有继承的功能,这是因为swift在本质上来说是面向协议(Protocol Oriented)的语言,struct没有也不需要继承的功能,为了实现某个功能,struct去服从并实现某个协议就即可,从一个较高的层次来看,struct+protocol是构成swift面向协议语言的两个基石。这一点不在本文讨论范围,不再赘述。

为什么要使用struct呢?总结就是struct可以保证代码更加安全可靠,以及struct+protocol更加切合swift面向协议编程的初衷。

enum

/*
- =左边的值是枚举值,例如 MON
- =右边的值在swift中称为 RawValue(原始值),例如 "MON"
- 两者的关系为:case 枚举值 = rawValue原始值
*/
enum Week: String{
    case MON = "MON"
    case TUE = "TUE"
    case WED = "WED"
    case THU = "THU"
    case FRI = "FRI"
    case SAT = "SAT"
    case SUN = "SUN"
}

enum Week1: String{
    case MON, TUE, WED = "WED", THU, FRI, SAT, SUN
}

//
//MON是从0开始一次递推,而WED往后是从10开始一次递推
enum Week2: Int{
    case MON, TUE, WED = 2, THU, FRI, SAT, SUN
}

enum Week3 {
    case work(day: Week2)
    case free(day: Week2)
}

mutating

struct Person {
    
    var name: String
    var age: Int
    var sex: Sex
    
    init(name: String, age: Int, sex: Sex) {
        self.age = age
        self.name = name
        self.sex = sex
    }
    
    func string() -> String {
        return "\(name) - \(age) - \(sex)"
    }
    
    func addAge(count: Int) {
        self.age += count
    }
}

error: Left side of mutating operator isn't mutable: 'self' is immutable Mark method 'mutating' to make 'self' mutable

说白了 struct/enum 内部声明的属性是内部不可变的(与值引用又一定关系),需要内部修改值那么需要申明 mutating 关键词进行标记

struct Person {
    
    var name: String
    var age: Int
    var sex: Sex
    
    init(name: String, age: Int, sex: Sex) {
        self.age = age
        self.name = name
        self.sex = sex
    }
    
    func string() -> String {
        return "\(name) - \(age) - \(sex)"
    }
    
    mutating func addAge(count: Int) {
        self.age += count
    }
}

你可能感兴趣的:(Swift 关键词 -- struct/enum/mutating)