enum,struck与class

来源:互联网 发布:电商平台用户数据分析 编辑:程序博客网 时间:2024/05/16 02:09

enum,struck与class

enum,struck和class的区别和联系?何时使用struck?何时用class?在struck实例方法中如何修改值类型?

enum

enum(枚举)为一组相关的值定义了一个共同的类型,使你可以在你的代码中以类型安全的方式来使用这些值。

用枚举表示四个方向:

enum CompassPoint {    case north    case south    case east    case west}

多个成员值可以出现在同一行上,并用逗号隔开:

enum CompassPoint {    case north, south, east, west}

注意

与 C 和 Objective-C 不同,Swift 的枚举成员在被创建时不会被赋予一个默认的整型值。在上面的CompassPoint例子中,north,south,east和west不会被隐式地赋值为0,1,2和3。相反,这些枚举成员本身就是完备的值,这些值的类型是已经明确定义好的CompassPoint类型。

struck和class

class SomeClass {    // 在这里定义类}struct SomeStructure {    // 在这里定义结构体}

在Swift中,enum和struck是值类型,class是引用类型

实际上,在 Swift 中,所有的基本类型:整数(Integer)、浮点数(floating-point)、布尔值(Boolean)、字符串(string)、数组(array)和字典(dictionary),都是值类型,并且在底层都是以结构体的形式所实现。

在 Swift 中,所有的结构体和枚举类型都是值类型。这意味着它们的实例,以及实例中所包含的任何值类型属性,在代码中传递的时候都会被复制。

Swift 中类和结构体有很多共同点。共同处在于:

  • 定义属性用于存储值
  • 定义方法用于提供功能
  • 定义下标操作使得可以通过下标语法来访问实例所包含的值
  • 定义构造器用于生成初始化值
  • 通过扩展以增加默认实现的功能
  • 实现协议以提供某种标准功能

与结构体相比,类还有如下的附加功能:

  • 继承允许一个类继承另一个类的特征
  • 类型转换允许在运行时检查和解释一个类实例的类型
  • 析构器允许一个类实例释放任何其所被分配的资源
  • 引用计数允许对一个类的多次引用

注意

结构体总是通过被复制的方式在代码中传递,不使用引用计数。

在struck实例方法中如何修改值类型?

结构体和枚举是值类型。默认情况下,值类型的属性不能在它的实例方法中被修改。

但是,如果你确实需要在某个特定的方法中修改结构体或者枚举的属性,你可以为这个方法选择可变(mutating)行为,然后就可以从其方法内部改变它的属性;

并且这个方法做的任何改变都会在方法执行结束时写回到原始结构中。方法还可以给它隐含的self属性赋予一个全新的实例,这个新实例在方法结束时会替换现存实例。

要使用可变方法,将关键字mutating 放到方法的func关键字之前就可以了:

struct Point {    var x = 0.0, y = 0.0    mutating func moveByX(deltaX: Double, y deltaY: Double) {        x += deltaX        y += deltaY    }}var somePoint = Point(x: 1.0, y: 1.0)somePoint.moveByX(2.0, y: 3.0)print("The point is now at (\(somePoint.x), \(somePoint.y))")// 打印 "The point is now at (3.0, 4.0)"

上面的Point结构体定义了一个可变方法 moveByX(_:y:) 来移动Point实例到给定的位置。该方法被调用时修改了这个点,而不是返回一个新的点。方法定义时加上了mutating关键字,从而允许修改属性。

注意

不能在结构体类型的常量(a constant of structure type)上调用可变方法,因为其属性不能被改变,即使属性是变量属性,

let fixedPoint = Point(x: 3.0, y: 3.0)fixedPoint.moveByX(2.0, y: 3.0)// 这里将会报告一个错误

值类型,引用类型的区别

值类型最基本的特征就是复制在赋值、初始化和传递参数过程中的数据,并为这个数据创建一个独立的实例:

// 值类型例子struct S { var data: Int = -1 }var a = S()var b = a                       // 把a复制给ba.data = 42                     // a被改变了, b却没有println("\(a.data), \(b.data)") // prints "42, -1"

复制一个引用类型的时候,其实是隐式地创建了一个共享的实例。在复制后,两个实例指向了同一块数据,所以当修改其中一个实例数据的时候,另一个实例的数据也被修改了,比如:

// 引用类型的例子class C { var data: Int = -1 }var x = C()var y = x                       // x被复制给了yx.data = 42                     // x指向的数据被修改了 (同时y也被修改了)println("\(x.data), \(y.data)") // prints "42, 42"

值类型用的时候是深复制,复制的是对象,对象有两份

引用类型用的时候是浅复制,复制的是指针,对象还是一份

原创粉丝点击