//: Playground - noun: a place where people can play
import UIKit
// # 类与结构体的对比
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()
let vga = Resolution(width: 640, height: 480) // 默认的成员初始化器
// # 结构体和枚举是值类型
// # 类是引用类型
var videoModeArray = [VideoMode]()
videoModeArray += [someVideoMode, someVideoMode] // 现在videoModeArray[0]和videoModeArray[1]都是对someVideoMode的引用
videoModeArray[0].interlaced = true
videoModeArray[1].interlaced
func setVideoModeName(videoMode: VideoMode, asName name: String) {
videoMode.name = name
}
setVideoModeName(videoMode: someVideoMode, asName: "New Mode!") // 可见在函数中改变了someVideoMode的值
someVideoMode.name!
// trick: 把类实例声明为常量和变量没有区别,都可以改变成员属性的值
var some = videoModeArray[1]
if videoModeArray[0] === some {
print("They refer to the same VideoMode instance")
} // 此时不能用==,因为没有定义VideoMode的运算符,对应的还有!==.而且可以发现,不管===左右是常量还是变量都无所谓
// # 类和结构体之间的选择
/* 下列情况考虑结构体:
结构体的主要目的是为了封装一些相关的简单数据值;
当你在赋予或者传递结构实例时,有理由需要封装的数据值被拷贝而不是引用;
任何存储在结构体中的属性是值类型,也将被拷贝而不是被引用;
结构体不需要从一个已存在类型继承属性或者行为。
*/
struct sd {
let some = VideoMode()
}
var s = sd()
var t = s
s.some.name = "Haha"
t.some.name // 可见,s和t中的some同时引用了一个实例,不过还是把sd变成class比较好,要不然发挥不了struct值类型的作用
// # 字符串,数组和字典的赋值与拷贝行为
// NSString , NSArray 和 NSDictionary实例总是作为一个已存在实例的引用而不是拷贝来赋值和传递。
网友评论