美文网首页
在 Swift 中 体会 class 与 struct 差异

在 Swift 中 体会 class 与 struct 差异

作者: kled_net | 来源:发表于2018-02-27 09:59 被阅读0次

    作为Swift中的另外一种自定义类型,从语法上来说,class和struct有很多相似的地方,例如:

    struct PointValue {
        var x: Int
        var y: Int
    }
    
    class PointRef {
        var x: Int
        var y: Int
        
        init(x: Int, y: Int) {
            self.x = x
            self.y = y
        }
    }
    

    可以看到,它们都可以用来自定义类型、都可以有properties,也都可以有methods。因此,单纯从语法上来理解class是个没什么意义的事情。在之前我们也说过,作为Swift中的引用类型,class表达的是一个具有明确生命周期的对象,我们需要关注这类内容的“生死存亡”,而值类型,我们更多关注的,就真的只是它的值而已。

    引用类型必须明确指明 init 方法

    首先,Swift并不会为class自动生成默认的init方法。如果我们不定义它,Swift编译器会报错。因此,无论多么简单的class,我们至少要为它定义一个初始化其所有属性的init方法。
    为什么要如此呢?前面提到了,class并不简单表达一个“值”的概念。Swift要求我们明确通过init方法说明“打造”一个对象的过程。相反,struct表达一个自定义的“值”,在没有特别说明的情况下,一个值的初始化当然是把它的每一个member都按顺序初始化。

    引用类型关注的是对象本身

    其次,class和struct对“常量”的理解是不同的。我们分别定义一个PointRef和PointValue的常量:

    let p1 = PointRef(x: 0, y: 0)
    let p2 = PointValue(x: 0, y: 0)
    

    同样是常量,当我们修改p2的属性时,编译器会报错:p2 is a let constant。但是我们却可以修改 p1 ,这是因为 p2 是一个值类型,常量的意义在于它的值不能被改变。但是 p1 是一个引用类型,这时候这个常量的意义则变成了:它可以修改自身的属性,但不能再引用其他的对象。
    除了这种语义上面的差别,我们还可以看到如果我们进行赋值操作,也会有差别

    var p3 = p1
    var p4 = p2
    

    这个时候 如果我们修改 p3 的属性那么 p1 的属性也会一起被修改,但是当我们修改 p4 的时候, p2 却并没有被修改。
    引用类型默认是可以修改属性的,这是因为引用类型关注的是其引用的对象而,不是对象的值。
    值类型却是默认情况下不允许修改属性的。如果你在写接口的时候,没有用mutating来修饰你的方法,那么使用你接口的人就要抓狂了。他无法对你的属性进行操作。(值类型的赋值操作就是基本的内存拷贝,因此你可以直接使用self进行赋值操作,编译器会自动将每一个属性值设置到self对应的属性。然而在引用类型中,self是一个常量,不能在引用其它对象)

    相关文章

      网友评论

          本文标题:在 Swift 中 体会 class 与 struct 差异

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