Swift学习-类和结构体(九)

来源:互联网 发布:c语言中括号数字 编辑:程序博客网 时间:2024/05/02 04:35

类和结构体对比

Swift中类和结构体有很多共同点。共同处在于:

定义属性用于储存值

定义方法用于提供功能

定义下标用于通过下标语法访问值

定义初始化器用于生成初始化值

通过扩展以增加默认实现的功能

符合协议以对某类提供标准功能


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

继承允许一个类继承另一个类的特征

类型转换允许在运行时检查和解释一个类实例的类型

取消初始化器允许一个类实例释放任何其所被分配的资源

引用计数允许对一个类的多次引用

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


//类和结构体命名,类型首字母大写, 属性和方法名首字母小写

//定义结构体 分辨率

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 someResoution is\(someResolution.width)")

// 输出:The width of someResoution is 0


// Objective-C语言不同的是,Swift 允许直接设置结构体属性的子属性。

someVideoMode.resolution.width =1280

print("The width of someVideoMode is now\(someVideoMode.resolution.width)")

// 输出:The width of someVideoMode is now 1280


//结构体类型的成员逐一初始化器对成员变量初始化,而类实例没有此功能

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

print("ss.width:\(ss.width)")

/*

 结构体和枚举是值类型

 值类型被赋予给一个变量,常数或者本身被传递给一个函数的时候,实际上操作的是其的拷贝。

*/

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

var cinema =hd

cinema.width = 80

print("hd.width:\(hd.width)  cinema.width:\(cinema.width)")

// 输出:hd.width:1920  cinema.width:80

//枚举

enum CompassPoint

{

   case North, South, East, West

}

var currDir =CompassPoint.West

let rememberedDir =currDir

currDir = .East

if rememberedDir== .West

{

    print("The remembered direction is still .West!")

}

//输出:The remembered direction is still .West!


//类是引用类型


let video =VideoMode()

video.resolution =hd

video.interlaced =true

video.name = "1080i"

video.frameRate = 25.0


let alsoVideo =video

alsoVideo.frameRate =30.0


print("video.frameRate:\(video.frameRate)")

//输出:video.frameRate:30.0


/*恒等运算

"==="等价于 “!==” 不等价于判定两个常量或者变量是否引用同一个类实例

*/

 ifvideo === alsoVideo {

    print("video and alsoVideo refer to the same Resolution instance")

}

//video and alsoVideo refer to the same Resolution instance



类和结构体的选择

在你的代码中,你可以使用类和结构体来定义你的自定义数据类型。


然而,结构体实例总是通过值传递,类实例总是通过引用传递。这意味两者适用不同的任务。

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


结构体的主要目的是用来封装少量相关简单数据值。

有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用。

任何在结构体中储存的值类型属性,也将会被拷贝,而不是被引用。

结构体不需要去继承另一个已存在类型的属性或者行为。

举例来说,以下情境中适合使用结构体:


几何形状的大小,封装一个width属性和height属性,两者均为Double类型。

一定范围内的路径,封装一个start属性和length属性,两者均为Int类型。

三维坐标系内一点,封装xyz属性,三者均为Double类型。

在所有其它案例中,定义一个类,生成一个它的实例,并通过引用来管理和传递。实际中,

这意味着绝大部分的自定义数据构造都应该是类,而非结构体。


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

Swift中字符串(String,数组(Array)和字典(Dictionary)类型均以结构体的形式实现。

这意味着StringArrayDictionary类型数据被赋值给新的常量或变量,或者被传入函数或方法中时,

它们的值会发生拷贝行为(值传递方式)。


Objective-C中字符串(NSString,数组(NSArray)和字典(NSDictionary)类型均以类的形式实现,

这与Swfit中以值传递方式是不同的。NSStringNSArrayNSDictionary在发生赋值或者传入函数(或方法)时,

不会发生值拷贝,而是传递已存在实例的引用。




0 0