import Foundation


//类和结构体是人们构建代码所用的一种通用且灵活的构造体。我们可以使用完全相同的语法规则来为类和结构体定义属性(常量、变量)和添加方法,从而扩展类和结构体的功能。


//与其他编程语言所不同的是,Swift 并不要求你为自定义类和结构去创建独立的接口和实现文件。你所要做的是在 一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口。


//注意: 通常一个 的实例被称为 对象 。然而在Swift ,类和结构体的关系要比在其他语言中更加的密 ,本章中所讨论的大部分功能都可以用在类和结构体上。因此,我们会主要使用 实例 而不是 对象





/*类和结构体对比********************************************************/

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

//? 定义属性用于存储值

//? 定义方法用于提供功能

//? 定义附属脚本用于访问值

//? 定义构造器用于生成初始化值

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

//? 实现协议以提供某种标准功能


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

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

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

//? 解构器允许一个类实例释放任何其所被分配的资源

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




/*定义********************************************************/

// 类和结构体有着类似的定义方式。我们通过关键字 class struct 来分别表示类和结构体,并在一对大括号中定 义它们的具体内容:

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? // 没有name

}




/*类和结构体实例********************************************************/

//生成结构体和类实例的语法非常相似:

let someResolution = Resolution()

let someVideoMode = VideoMode()




/*属性访问********************************************************/

//通过使用点语法(dot Syntax),你可以访问实例中所含有的属性

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"


// Objective-C 语言不同的是,Swift 允许直接设置结构体属性的子属性。上面的最后一个例子,就是 直接设置了 someVideoMode resolution 属性的 width 这个子属性,以上操作并不需要重新设置 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 本身。

cinema.width = 2048

print("cinema is Now \(cinema.width) pixels wide")

// 输出 "cinema is Now 2048 pixels wide"

print("hd is still \(hd.width ) pixels wide")

// 输出 "hd is still 1920 pixels wide"


//在将 hd 赋予给 cinema 的时候,实际上是将 hd 中所存储的值(values) 进行拷贝,然后将拷贝的数据存储到 新的 cinema 实例中。结果就是两个完全独立的实例碰巧包含有相同的数值。由于两者相互独立,因此将 cinema width 修改为 2048 并不会影响 hd 中的 width 的值。

//枚举也遵循相同的行为准则:

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

// 输出 "The frameRate property of theEighty is Now 30.0"

//如果能够判定两个常量或者变量是否引用同一个类实例将会很有帮助。为了达到这个目的,Swift 内建了两个恒等 运算符

// 等价于 ( === )

// 不等价于 ( !== )

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 类型。





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

********************************************************/

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


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


//注意: 以上是对于字符串、数组、字典和其它值的 拷贝 的描述。 在你的代码中,拷贝好像是确实是在有拷贝 行为的地方产生过。然而, Swift 的后台中,只有确有必要,实际(actual) 拷贝才会被执行。Swift 管理所 有的值拷贝以确保性能最优化的性能,所以你也没有必要去避免赋值以保证最优性能。(实际赋值由系统管理优 )

《swift2.0 官方教程中文版》 第2章-09类和结构体的更多相关文章

  1. 寒城攻略:Listo 教你 25 天学会 Swift 语言 - 13 Methods

    方法还可以给它隐含的self属性赋值一个全新的实例,这个新实例在方法结束后将替换原来的实例structPoint1{0.0,y=mutatingfuncmoveByX{x+=deltaXy+=deltaY}}varsomePoint1=Point1">1.0)注意定义结构体实例时必须为变量不能为常量somePoint1moveByX2.03.0)")//在变异方法中给self赋值structPoint2{Double){self=Point2}}varsomePoint2=Point2(x:somePoi

  2. 【Swift初见】Swift结构体

    访问rect这个实例里面的width和height方法也是用点语法:这样我们就完成了一个结构体的定义和创建一个结构体实例。结构体的成员方法:与C还有OC结构体不一样的是,swift的结构体可以包含成员方法,即行为,这就跟面向对象中的类的概念比较类似:我们给刚刚Rect结构体加上一个面积的方法:我们可以看出,方法的定义跟外部全局函数的定义是一样的,那么如何使用该成员方法呢?

  3. 寒城攻略:Listo 教你 25 天学会 Swift 语言 - 21 Nested Types

    //***********************************************************************************************//1.nestedTypes(类型嵌套)//________________________________________________________________________________

  4. Swift语法基础:5 - Swift的枚举和结构体

    在Siwft中的枚举类型以及结构体,是和OC中差不多的,但Swift中又有一些特性,下面让我们来看看:1.枚举的声明及使用PS:这里解释一下,枚举类型第一个开始的参数都是1,无论你是有多少case,都会递增的,比如例子的的Ace是1,那么Two就是名副其实的2,Three就是3,以此类推,一直到King,就是13,而enum里面有一个方法,这里面这个方法只是说可以在enum里定义方法,但我这个例子

  5. Swift语法基础:6 - Swift的Protocol和Extensions

    前面我们知道了枚举类型和结构体的声明,嵌套,以及基本的使用,现在让我们来看看Swift中的另外两个,一个是Protocol(协议),一个是Extensions(类别):1.声明ProtocolPS:在声明协议的时候,如果你要修改某个方法属性,你必须的在该方法前加上mutating这个关键字,否则不能修改.2.使用Protocol同样的,在结构体里一样可以使用,但是必须的加上mutating:Protocol也可以这么使用:PS:这里的a是前面例子里面的a.3.声明Extensions好了,这次我们就讲到这

  6. Swift面向对象的类型

    1、类2、结构体3、枚举在swift语言中通过类和结构体实现面向对象,在Swift语言中,枚举也具有面向对象的特性示例和对象在面向对象中,将类创建对象的过程称为实例化,因此将对象称为实例化,但是在swift中,枚举和结构体不能称为对象,因为结构体和枚举并不是彻底的面向对象类型,而是只包含了一些面向对象的特定,例如,在Swift中继承只发生在类上,结构体和枚举不能继承

  7. Swift基础语法: 25 - Swift的类和结构体

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

  8. Swift编程高级教程 变量与常量

    提示实际应用中很少需要指定变量数据类型,Swift会根据所设置的值的类型进行推导。Swift使用字符串插值来输出变量和常量。Swift中并没有所谓的实例变量,而是将它们统一为属性了,这样使得属性的声明更加简化。Size封装了宽度和高度。而let只能用于常量的声明,表示它们的值不能发生改变。但是在Swift中可以直接将它们定义为类型的一部分。

  9. Swift中结构体(Struct)和类(Class)的区别

    今天這個篇文章要來介紹Swift中struct和class有什麼不一樣的地方?不过要提醒大家在Swift常用的String,Array,Dictionary都是struct所以let是会有效果的4.mutatingfunction我們先要為struct和class新增一個method名為changeWidth()而且我們在不改变原始的程式碼為前提下,新增一個method。如下structSRectangle{varwidth=200}extensionSRectangle{mutatingfuncchan

  10. Swift教程12-数组的结构体本质,对比NSArray

    Swift中的数组要求在创建时其存储的类型是确定的,这点与Oc中的数组有一些不同;当然,这也不是绝对的,因为有时候数组可以使用范型来约束其类型,只需遵循相应的协议即可,类型并不是完全一致的.Swift中的数组相比于Oc的数组,功能更加强大;使用更加简便;当然也更加复杂了(光是Array的代码就有9800多行)1.数组的本质,查看官方的API可以知道数组实际上是一个结构体.可以看到数组的构成包括:范

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部