swift2 类和结构体

定义


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)")
// 输出 "The width of someResolution is 0"
print("The width of someVideoMode is \(someVideoMode.resolution.width)")
// 输出 "The width of someVideoMode is 0"

someVideoMode.resolution.width = 1280
print("The width of someVideoMode is now \(someVideoMode.resolution.width)")
// 输出 "The width of someVideoMode is now 1280"



结构体成员逐一构造器

所有结构体都有一个自动生成的成员逐一构造器,用于初始化新结构体实例中成员的属性。
新实例中各个属性的初始值可以通过属性的名称传递到成员逐一构造器之中:

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

与结构体不同,类实例没有默认的成员逐一构造器。



结构体和枚举是值类型


let hd = Resolution(width: 1920,height: 1080)
var cinema = hd
cinema.width = 2048
print("cinema is now  \(cinema.width) pixels wide")
// 输出 "cinema is now 2048 pixels wide"
//然而,初始的hd实例中width属性还是1920
print("hd is still \(hd.width    ) pixels wide")
// 输出 "hd is still 1920 pixels wide"

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")
}
// 输出 "The remembered direction is still .West"


类是引用类型


let hd = Resolution(width: 1920,height: 1080)
let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0

let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0

print("The frameRate property of tenEighty is now \(tenEighty.frameRate)")
// 输出 "The frameRate property of theEighty is now 30.0"

需要注意的是tenEighty和alsoTenEighty被声明为常量((constants)而不是变量。
然而你依然可以改变tenEighty.frameRate和alsoTenEighty.frameRate,因为这两个常量本身不会改变。
它们并不存储这个VideoMode实例,在后台仅仅是对VideoMode实例的引用。
所以,改变的是被引用的基础VideoMode的frameRate参数,而不改变常量的值。



恒等运算符


if tenEighty === alsoTenEighty {
    print("tenEighty and alsoTenEighty refer to the same Resolution instance.")
}
//输出 "tenEighty and alsoTenEighty refer to the same Resolution instance."

请注意“等价于"(用三个等号表示,===) 与“等于"(用两个等号表示,==)的不同:
“等价于”表示两个类类型(class type)的常量或者变量引用同一个类实例。
“等于”表示两个实例的值“相等”或“相同”,判定时要遵照类设计者定义定义的评判标准,因此相比于“相等”,这是一种更加合适的叫法。


类和结构体的选择


结构体实例总是通过值传递,类实例总是通过引用传递。这意味两者适用不同的任务。
当你在考虑一个工程项目的数据构造和功能的时候,你需要决定每个数据构造是定义成类还是结构体。

结构体的主要目的是用来封装少量相关简单数据值。
有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用。
任何在结构体中储存的值类型属性,也将会被拷贝,而不是被引用。
结构体不需要去继承另一个已存在类型的属性或者行为。

合适的结构体候选者包括:
几何形状的大小,封装一个width属性和height属性,两者均为Double类型。
一定范围内的路径,封装一个start属性和length属性,两者均为Int类型。
三维坐标系内一点,封装x,y和z属性,三者均为Double类型。

在所有其它案例中,定义一个类,生成一个它的实例,并通过引用来管理和传递。实际中,这意味着绝大部分的自定义数据构造都应该是类,而非结构体。



集合类型的赋值和拷贝


Swift 中字符串(String),数组(Array)和字典(Dictionary)类型均以结构体的形式实现。
这意味着String,Array,Dictionary类型数据被赋值给新的常量(或变量),或者被传入函数(或方法)中时,它们的值会发生拷贝行为(值传递方式)。

Objective-C中字符串(NSString),数组(NSArray)和字典(NSDictionary)类型均以类的形式实现,这与Swfit中以值传递方式是不同的。
NSString,NSArray,NSDictionary在发生赋值或者传入函数(或方法)时,不会发生值拷贝,而是传递已存在实例的引用。

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...