属性在前面的枚举,类,结构体中都已经使用过,本章介绍属性的性质和方法
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
struct FixedLengthRange { var firstValue: Int let length: Int}var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)// the range represents integer values 0, 1, and 2rangeOfThreeItems.firstValue = 6// the range now represents integer values 6, 7, and 8//如果结构体的实例就是let类型,则第一次初始化后,不能再修改其任何属性的值let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)// this range represents integer values 0, 1, 2, and 3rangeOfFourItems.firstValue = 6// 将会报错 |
但是类不同意结构体,因为类是指针类型,将指针类型的实例赋值给一个常量,仍然可以修改其变量成员的值。
延迟存储属性,在属性声明前部加@lazy关键字,必须是var类型的属性才能是延迟属性,延迟属性只有在用到时才会被计算。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
class DataImporter { /* 该类的功能是从外部文件导入数据 */ var fileName = "data.txt" // 其他数据导入等功能此处省略} class DataManager { @lazy var importer = DataImporter() var data = String[]() // 其他数据管理功能此处省略} let manager = DataManager()manager.data += "Some data"manager.data += "Some more data"//在下面的语句执行以前,importer未被创建println(manager.importer.fileName)// 当第一次用到importer的时候,才会生成实例,打印"data.txt" |
存储属性:我认为就是一般的属性,直接存储了变量或常量,可直接通过后点(.)获得或设置其值
计算属性:有get方法和set(可选)方法的属性
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
struct Point { var x = 0.0, y = 0.0}struct Size { var width = 0.0, height = 0.0}struct Rect { var origin = Point() var size = Size() var center: Point { get { let centerX = origin.x + (size.width / 2) let centerY = origin.y + (size.height / 2) return Point(x: centerX, y: centerY) } set(newCenter) { origin.x = newCenter.x - (size.width / 2) origin.y = newCenter.y - (size.height / 2) } }}var square = Rect(origin: Point(x: 0.0, y: 0.0),size: Size( 10.0, height: 10.0))//调用了center的get方法,计算了Pointlet initialSquareCenter = square.center//调用了center的set方法,origin被修改了square.center = Point(x: 15.0, y: 15.0)println("square.origin is now at ((square.origin.x), (square.origin.y))")// origin现在是 (10.0, 10.0) |
set方法可以省略参数,省略时,默认用newValue代替,如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
struct AlternativeRect { var origin = Point() var size = Size() var center: Point { get { let centerX = origin.x + (size.width / 2) let centerY = origin.y + (size.height / 2) return Point(x: centerX, y: centerY) } set { origin.x = newValue.x - (size.width / 2) origin.y = newValue.y - (size.height / 2) } }} |
只有get方法的计算属性是只读的,可以省略get,语法如下:
|
1
2
3
4
5
6
7
8
9
|
struct Cuboid { var width = 0.0, height = 0.0, depth = 0.0 var volume: Double { return width * height * depth }}let fourByFiveByTwo = Cuboid( 4.0, height: 5.0, depth: 2.0)println("the volume of fourByFiveByTwo is (fourByFiveByTwo.volume)")// 打印"the volume of fourByFiveByTwo is 40.0" |
属性监视器,允许开发者在设置变量值前后执行一段代码
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
class StepCounter { var totalSteps: Int = 0 { willSet(newTotalSteps) { println("About to set totalSteps to (newTotalSteps)") } didSet { //参数省略时,默认使用oldValue,willSet的参数也可省略,默认是newValue //在didSet方法里也可以修改本属性的值,并且在次数的赋值不调用willSet和didSet if totalSteps > oldValue { println("Added (totalSteps - oldValue) steps") } } }}let stepCounter = StepCounter()//每设置一次totalSteps 的值,都执行willSet和didSet各一次,初始化时都不执行stepCounter.totalSteps = 200// About to set totalSteps to 200// Added 200 stepsstepCounter.totalSteps = 360// About to set totalSteps to 360// Added 160 stepsstepCounter.totalSteps = 896// About to set totalSteps to 896// Added 536 steps |
全局变量一般都是计算延迟的,类似延迟存储变量, 但是不需要在前面加@lazy关键字
类型属性就是属于类型的属性,想C++中静态变量,只存在一份,在所有类的实例中共享。
值类型(结构体和枚举)可以定义存储变量和计算变量的类型属性,而指针类型(类)只能定义计算变量的类型属性
而存储类型属性可以是var和let型的,而计算类型属性只能是var型的
必须给存储类型属性赋初值,因为类型在初始化不能对存储类型属性赋值
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
//声明类型属性struct SomeStructure { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { // return an Int value here }}enum SomeEnumeration { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { // return an Int value here }}class SomeClass { class var computedTypeProperty: Int { // return an Int value here }}//使用和赋值类型属性,使用类型调用类型属性println(SomeClass.computedTypeProperty) println(SomeStructure.storedTypeProperty)// 打印 "Some value."SomeStructure.storedTypeProperty = "Another value."println(SomeStructure.storedTypeProperty)// 打印"Another value." |