分类 标签 存档 黑客派 订阅 搜索

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

40 浏览

类和结构体对比

共同处:

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

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

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

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

定义语法

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?
}

类和结构体实例

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

属性访问

//访问属性
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设置新值.

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

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

结构体和枚举是值类型

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

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

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

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")
}

类是引用类型

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 实例.

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

1. 恒等运算符

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

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

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--

评论  
留下你的脚步
推荐阅读