Swift(十四)类和结构体

Swift(十四)类和结构体_第1张图片
e28d38185d2247ea1c0e1ef5e0ecb5a3c030af1591d1c-a6qT3U_fw658.png

在swift中, 结构体被重新定义, 它用于很多类所拥有的功能, 几乎可以和类媲美, 但是在存储数据方面有区别, 类是引用类型, 结构体是值类型, 所以要根据存储数据的类型和使用环境来选择不同的数据结构

类和结构体定义

struct Resolution { 
    var width = 0 
    var heigth = 0  //赋初值
} 
class VideoMode { 
    var resolution = Resolution() 
    var interlaced = false 
    var frameRate = 0.0 
    var name: String?  //name属性会被自动赋予一个默认值nil,意为“没有name值”,因它是一个可选类型。
} 

生成结构体和类实例的语法非常相似:

let someResolution = Resolution() 
let someVideoMode = VideoMode() 

结构体和类的访问和OC一样, 都可以通过.语法,访问属性和子属性

someVideoMode.resolution.width //使用点语法访问
someVideoMode.resolution.width = 1024 //使用点语法赋值

注意:与 Objective-C 语言不同的是,Swift 允许直接设置结构体属性的子属性。上面的最后一个例子,就是直接设置了someVideoMode中resolution属性的width这个子属性,以上操作并不需要从新设置resolution属性。记不记得在OC当中, 你如果要修改一个结构体,, 例如CGRect, 你不可以直接修改frame.origin.y的值, 而是需要构造一个新的CGRect, 然后把这个修改好的CGRect赋值给原来的CGrect

CGRect frame;
frame.origin.x = 100; //这样是修改不了的

结构体和枚举是值类型

在 Swift 中,所有的基本类型:整数(Integer)、浮点数(floating-point)、布尔值(Booleans)、字符串(string)、数组(array)和字典(dictionaries),都是值类型,并且都是以结构体的形式在后台所实现。
在 Swift 中,所有的结构体和枚举都是值类型。这意味着它们的实例,以及实例中所包含的任何值类型属性,在代码中传递的时候都会被复制。

let tenEighty = VideoMode() //创建一个类并赋值给tenEighty
tenEighty.frameRate = 25.0 //修改tenEighty. tenEighty.frameRate的值
let alsoTenEighty = tenEighty //把tenEighty赋值给一个新的常量
alsoTenEighty.frameRate = 30.0 //使用新的常量修改frameRate的值
print(tenEighty.frameRate) //30.0 

需要注意的是tenEighty和alsoTenEighty被声明为常量(let)而不是变量。然而你依然可以改变tenEighty.frameRate和alsoTenEighty.frameRate,因为这两个常量本身不会改变。它们并不储存这个VideoMode实例,在后台仅仅是对VideoMode实例的引用。修改其中一个的值会影响到另外一个, 由此可证明, 他们使用的是同一份数据, 即引用的是同一个对象. 所以,改变的是被引用的基础VideoMode的frameRate参数,而不改变常量的值.(这一点与OC不同)

    Person *p = [[Person alloc] init];
    p.name = @"小米";
    Person *p1 = p;
    p1.name = @"大米";
    NSLog(@"%@, %@", p1.name, p.name); //大米, 大米

类和结构体的选择

在你的代码中,你可以使用类和结构体来定义你的自定义数据类型。

然而,结构体实例总是通过值传递,类实例总是通过引用传递。这意味两者适用不同的任务。当你的在考虑一个工程项目的数据构造和功能的时候,你需要决定每个数据构造是定义成类还是结构体。

按照通用的准则,当符合一条或多条以下条件时,请考虑构建结构体:

结构体的主要目的是用来封装少量相关简单数据值。

有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用。

任何在结构体中储存的值类型属性,也将会被拷贝,而不是被引用。

结构体不需要去继承另一个已存在类型的属性或者行为。

集合(Collection)类型的赋值和拷贝行为

Swift 中数组(Array)和字典(Dictionary)类型均以结构体的形式实现。然而当数组被赋予一个常量或变量,或被传递给一个函数或方法时,其拷贝行为与字典和其它结构体有些许不同。

以下对数组和结构体的行为描述与对NSArray和NSDictionary的行为描述在本质上不同,后者是以类的形式实现,前者是以结构体的形式实现。NSArray和NSDictionary实例总是以对已有实例引用,而不是拷贝的方式被赋值和传递。

注意:以下是对于数组,字典,字符串和其它值的拷贝的描述。 在你的代码中,拷贝好像是确实是在有拷贝行为的地方产生过。然而,在Swift 的后台中,只有确有必要,实际(actual)拷贝才会被执行。Swift 管理所有的值拷贝以确保性能最优化的性能,所以你也没有必要去避免赋值以保证最优性能。(实际赋值由系统管理优化)

var a = [1, 2, 3] 
var b = a 
var c = a 
a[0] = 42 
//修改原来的值, 不会对其他的值产生影响, 字典同样
println(a[0]) // 42  
println(b[0]) // 1
println(c[0]) //1

你可能感兴趣的:(Swift(十四)类和结构体)