Swift学习笔记五-类和结构体

类和结构体对比

共同处:

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

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

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

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

定义语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class SomeClass {
//class definition goes here
}
struct SomeStructure {
//structure definition goes here
}
//定义结构体和定义类的实例:
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name:String?
}

类和结构体实例

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

属性访问

1
2
3
4
5
6
7
8
//访问属性
print("The width of someResolution is \(someResolution.width)")
//访问子属性
print("The width of someVideoMode is \(someVideoMode.resolution.width)")
//给变量赋值
someVideoMode.resolution.width = 1280
print("The width of someVideoMode is now \(someVideoMode.resolution.width)")
//注意:与OC不同,Swift允许直接设置结构体属性的子属性.并不需要为整个resolution设置新值.

结构体类型的成员逐一构造器

1
let vga = Resolution(width: 640, height: 480)

结构体和枚举是值类型

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

1
2
let hd = Resolution(width: 1920, height: 1080)
var cinema = hd

因为Resolution是一个结构体,所以cinema的值是hd的一个拷贝副本,而不是hd本身.
枚举也遵循相同的行为准则:

1
2
3
4
5
6
7
8
9
enum CompassPoint {
case North, South, East, West
}
var currentDirection = CompassPoint.West
let rememberedDirection = currentDirection
currentDirection = .East
if rememberedDirection == .West {
print("The remembered direction is still .West")
}

类是引用类型

1
2
3
4
5
6
7
let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0

因为类是引用类型,所以tenEight和alsoTenEight实际上引用的是相同的VideoMode实例.

1
2
print("The frameRate property of tenEighty is now \(tenEighty.frameRate)")
//tenEigty.frameRate此时是30.0

1.恒等运算符

  1. === 等价于
  2. !== 不等价于

运用这两个运算符检测连个常量或者变量是否引用同一个实例:

1
2
3
if tenEighty === alsoTenEighty {
print("tenEighty and alsoTenEighty refer to the same Resolution instance")
}

注意:”等价于”(用三个等号表示,===)与”等于”(用两个等号表示,==)不同:

  • “等价于”表示两个类类型(class type)的常量或者变量引用同一个类实例

  • “等于”表示两个市里的值”相等”或”相同”,相对于”相等”来说,这种叫法更合适.

2.指针

与C语言中的指针类似,但是并不直接只想某个内存地址,Swift中的这些引用与其它常量或者变量的定义方式相同.

类和结构体的选择

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

  • 该数据结构的主要目的是用来封装少量相关简单数据值.
  • 有理由语句该数据结构的实例在被赋值或者传递时,封装的数据将被拷贝而不是被引用.
  • 该数据结构中存储的值类型属性,也应该被拷贝,而不是被引用.
  • 该数据结构不需要去继承另一个既有类型的属性或者行为.

举例,以下情景适合使用结构体:

  • 几何形状的大小,封装一个 width 属性和 height 属性,两者均为 Double 类型。
  • 一定范围内的路径,封装一个 start 属性和 length 属性,两者均为 Int 类型。
  • 三维坐标系内一点,封装 x , y 和 z 属性,三者均为 Double 类型.

    字符串(String)、数组(Array)、和字典(Dictionary)类型的赋值与复制行为

    Swift 中,许多基本类型,诸如 String , Array 和 Dictionary 类型均以结构体的形式实现。这意味着被赋值给 新的常量或变量,或者被传入函数或方法中时,它们的值会被拷贝。

Objective-C 中 NSString , NSArray 和 NSDictionary 类型均以类的形式实现,而并非结构体。它们在被赋值或 者被传入函数或方法时,不会发生值拷贝,而是传递现有实例的引用。
–EOF–