Swift基本语法(二)

枚举

定义

枚举为一组相关的值定义了一个共同的类型,使你可以在你的代码中以类型安全的方式来使用这些值。Swift中枚举与C和Objective-C不同,这些枚举成员本身就是完整的值,这些值的类型是已经明确定义好的CompassPoint类型。枚举名字必须以一个大写字母开头。

1
2
3
4
5
6
7
8
enum CompassPoint {
case North
case South
case East
case West
}
//枚举多个成员可以出现在同一行,用逗号隔开

枚举定义了一个全新的类型,所有首字母必须大写。

1
2
3
4
var direction = CompassPoint.East
//简化
direction = .East

使用switch语句匹配枚举值

1
2
3
4
5
6
7
8
9
10
11
switch direction {
case .North:
print("North")
case .East:
print("East")
case .South:
print("South")
case .West:
print("West")
}

当不需要全部匹配的时候,使用default。

关联值

1
2
3
4
5
6
7
8
9
10
// 定义两种商品条形码的枚举
enum Barcode {
case UPCA(Int, Int, Int, Int)
case QRCode(String)
}


var productBarcode = Barcode.UPCA(8, 85909, 52233, 3)
productBarcode = .QRCode("ABCDJLJELKJLE")

Barcode类型的常量和变量可以存储一个.UPCA或者.QRCode。同一时间只能存储这两个值得一个值。

递归枚举

在枚举类型前加indirect来表示该枚举所有成员可递归。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
indirect enum ArithmeticExpression {
case Number(Int)
case Addition(ArithmeticExpression, ArithmeticExpression)
case Multipliation(ArithmeticExpression, ArithmeticExpression)
}

func evaluate(expression: ArithmeticExpression) -> Int {
switch expression {
case .Number(let value):
return value
case .Addition(let left, let right):
return evaluate(left) + evaluate(right)
case .Multipliation(let left, let right):
return evaluate(left) * evaluate(right)
}
}

//计算 ( 5 + 4 ) * 2
let five = ArithmeticExpression.Number(4)
let four = ArithmeticExpression.Number(5)
let sum = ArithmeticExpression.Addition(five, four)
let product = ArithmeticExpression.Multipliation(sum, ArithmeticExpression.Number(2))
print(evaluate(product)) //输出结果 18

类和结构体

两者比较

共同点:

  • 定义属性用于存储值
  • 定义方法用于提供功能
  • 定义附属脚本用于访问值
  • 定义构造器用于生产初始化值
  • 通过扩展以增加默认实现的功能
  • 实现协议以提供某种标准功能

类附加功能

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

在Swift中 结构体是值类型,String, Array和Dictionary 类型均以结构体的形式实现, 在被赋值给新的常量或变量,或者被传入函数或方法中时,会进行值拷贝。另外,类是引用类型。在Objective-C中NSString, NSArray和NSDictionary类型均以类的形式实现。

属性

存储属性

一个存储属性就是存储在特定类或结构体的实例里的一个常量或变量。

1
2
3
4
5
6
7
8
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3) // 该区间表示整数0,1,2
rangeOfThreeItems.firstValue = 6
// 该区间现在表示整数6,7,8

延迟存储属性

延迟存储属性是指当第一次被调用的时候才去计算初始值的属性。使用lazy修饰,例如:

1
2
3
lazy var importer = DataImporter()
// 耗时操作,用到的时候再去创建。

计算属性

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
29
30
31
struct Point {
var x = 0.0, y = 0.0
}
//封装了一个width和height
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)
}
//如果setter没有定义新值得参数名,则可以使用默认名称newValue
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(width: 10.0, height: 10.0))
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y: 15.0)
print("原点为:(\(square.origin.x),\(square.origin.y))")

属性观察器

属性观察器监控和响应属性值的变化,每次属性被设置值得时候都会调用属性观察器。
属性观察器:

  • willSet在新的值被设置之前调用,将新的值作为常量参数传入,默认名称newValue
  • didSet在新的值被设置之后立即调用,将新的值作为常量参数传入,默认名称oldValue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class StepCounter {
//添加两个观察器
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
print("About to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
print("Added \(totalSteps - oldValue) steps")
}
}
}
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// Added 160 steps
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps

注意: 在didSet观察器中给属性赋值,这个值会替换之前的设置的值。

类型属性

使用关键字static定义

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
struct SomeStruce {
static var storedTypeProperty = "Some value"
static var computedTypeProperty: Int {
return 1
}
}
enum SomeEnumeration {
static var storedTypeProperty = "Some value"
static var computedTypeProperty: Int {
return 6
}
}
class SomeClass {
static var storedTypeProperty = "Some value"
static var computedTypeProperty: Int {
return 27
}
class var overrideableComputedTypeProperty:Int {
return 107
}
}
//获取和设置类型属性的值
print(SomeStruce.storedTypeProperty)
SomeStruce.storedTypeProperty = "Another value"





**注意:类型属性是通过类型本身来获取和设置,而不是通过实例。**


struct AudioChannel {
static let thresholdLevel = 10
static var maxInputLevelForAllChannels = 0
var currentLevel: Int = 0 {
didSet {
if currentLevel > AudioChannel.thresholdLevel {
//限制最大值
currentLevel = AudioChannel.thresholdLevel
}
if currentLevel > AudioChannel.maxInputLevelForAllChannels {
//保存新值
AudioChannel.maxInputLevelForAllChannels = currentLevel
}
}
}
}

小结

本文学习整理了枚举,类和结构体,属性等相关知识。

参考资料

The Swift Programming Language