美文网首页swiftswift
swift mutating关键字

swift mutating关键字

作者: ikonan | 来源:发表于2018-08-03 12:47 被阅读2次

    在Swift中,包含三种类型struct, enum, class

    其中struct和enum是值类型, class是引用类型,但是与Objective-C不同的是,structureenumeration也可以拥有方法(method),其中方法可以为实例方法,也可以为类方法,实例方法是和类型的一个实例绑定的。

    mutating 用法

    一、Struct Mutable 的⽅法

    在 Swfit 中我们基本都是⽤ struct 去定义⼀个纯数据类型。⽐如

    struct User {
      var age : Int
      var weight : Int
      var height : Int
    }
    

    ⽽有我们经常会在变量⾥添加⼀些简单的改变变量⾥内容的⽅法,⽐如

    func gainWeight(newWeight: Int) {
      weight += newWeight
    }
    

    但如果我们直接把这个⽅法放⼊ User 这个变量中间,你的编译器就会给出⼀个⾮常奇怪的错误消息

    struct User {
      var age : Int
      var weight : Int
      var height : Int
      func gainWeight(newWeight: Int) {
        weight += newWeight
      }
    }
    

    错误的消息竟然是 Binary operator '+=' cannot be applied to two int operands ,意思是在2个数字之间没有办法使⽤ += 。但⼤家都知道 += 在数字变量之间是最常⻅不过的,为什么不能⽤?

    其实在这个错误代码后⾯有另⼀层意思。因为我们忽略了⼀点,Struct 出来的变量是 Immutable的,想要⽤⼀个⽅法去改变变量⾥⾯的值的时候必须要加上⼀个关键词 mutating ,所以其实这个错误代码的真正含义应该是 因为 User 的 Weight 是 Immutable 的,所以+= ⽆法在这两个 Int 上使⽤我们在⽅法之前加上 mutating 之后编译就可以顺利进⾏了

    struct User {
      var age : Int
      var weight : Int
      var height : Int
      mutating func gainWeight(newWeight: Int) {
        weight += newWeight
      }
    }
    

    二、将protocol 的⽅法声明为 mutating

    Swift 的 protocol 不仅可以被 class 类型实现,也适⽤于 struct 和 enum 。因为这个原因,我们在写给别⼈⽤的接⼝时需要多考虑是否使⽤ mutating 来修饰⽅法,⽐如定义为 mutating func myMethod() 。Swift 的 mutating 关键字修饰⽅法是为了能在该⽅法中修改 struct 或是 enum 的变量,所以如果你没在接⼝⽅法⾥写 mutating 的话,别⼈如果⽤ struct 或者 enum 来实现这个接⼝的话,就不能在⽅法⾥改变⾃⼰的变量了。⽐如下⾯的代码

    protocol Vehicle {
        var numberOfWheels: Int {get}
        var color: UIColor {get set}
        
        mutating func changeColor()
    }
    
    struct Car: Vehicle {
        let numberOfWheels = 4
        var color = UIColor.blue
        
        mutating func changeColor() {
            color = UIColor.red
        }
    }
    

    如果把 protocol 定义中的 mutating 去掉的话, Car 就怎么都过不了编译了:保持现有代码不变的话,会报错说没有实现接⼝;如果去掉 mutating 的话,会报错说不能改变结构体成员。这个接⼝的使⽤者的忧伤的眼神,相信你能想象得出。另外,在使⽤ class 来实现带有 mutating 的⽅法的接⼝时,具体实现的前⾯是不需要加mutating 修饰的,因为 class 可以随意更改⾃⼰的成员变量。所以说在接⼝⾥⽤ mutating 修饰⽅法,对于 class 的实现是完全透明,可以当作不存在的。

    相关文章

      网友评论

        本文标题:swift mutating关键字

        本文链接:https://www.haomeiwen.com/subject/wcuyvftx.html