Swift学习笔记:类和结构

一、类和结构的异同

类和结构有一些相似的地方,它们都可以:

1. 定义一些可以赋值的属性;

2. 定义具有功能性的方法

3. 定义下标,使用下标语法

4. 定义初始化方法来设置初始状态

5. 在原实现方法上的可扩展性

根据协议提供某一特定类别的基本功能

1. 类还有一些结构不具备的特性:

2. 类的继承性

3. 对类实例实时的类型转换

4. 析构一个类的实例使之释放空间

5. 引用计数,一个类实例可以有多个引用

1. 定义语法

struct Name{
    let firstName = ""
    let secondName = ""
}
class Student{
    var name = Name()
    var height = 0.0
    var score = 0
}
let a = Student()

如代码所示,我们定义了一个结构体Name和一个类Student。在定义结构体和类的过程中有以下几点需要注意

注意:

① 基于书写规范,结构体和类的定义最好首字母大写

② 结构体和类的定义中,每个属性均需要给出默认值,否则编译器会报错

2. 访问属性以及结构类型初始化

let name1 = Name(firstName:"小",secondName:"本狼")
let a = Student()
a.name = name1;
a.height = 185

上面的代码中,首先我们初始化了Name结构体的一个实例name1,然后初始化了Student类的实例,并对这个实例进行赋值。重点有以下几个方面

重点:

① 结构体的初始化可以像调用外部函数一样,通过属性名称指定初始值

② 属性的访问,在实例后加上“.”再加上属性名称即可访问属性

注意:

① 和结构不同,类实例不能够使用成员初始化方法,类的初始化会在后面专门介绍

② 和Objective-C不同,Swift能够直接设置一个结构属性的子属性

二、结构和枚举类型是数值类型

数值类型是说当它被赋值给一个常量或者变量,或者作为参数传递给函数时,是完整地复制了一个新的数值,而不是仅仅改变了引用对象。

struct Name{
    var firstName = ""
    var secondName = ""
}
var a = Name(firstName:"小",secondName:"笨狼")
var b = a
a.firstName = "大"
println(b.firstName)    //输出:小

如上面的例子所示,结构类型的赋值是完整的创建一个新的值,原来对象改变不会对赋值对象产生任何影响

、类是引用类型

和结构类型不一样,类是属于引用类型,类的赋值只是用引用赋值

struct Name{
    var firstName = ""
    var secondName = ""
}
class Student{
    var name = Name()
    var height = 0
    var score = 0
}
let a = Student()
let b = a
a.score = 98
println(b.score)    //输出:98

如上面的例子所示,将a对b赋值,a的属性改变,b的属性也会随之改变,因为a和b是2个指针,他们都指向同一地址

四、特征操作

判断2个对象是否指向同一个实例地址。需要用===和!==来判断

let a = Student()
let b = a
if a === b{
    println("a=b")
}else{
    println("a != b")
}   //输出 a=b

如上面的代码所示,a和b指向同一个实例,会输出a=b。

注意:

① 这并不是判断他们是否属于同一个类,如果b是Student类的另一个实例,则会不相等

② 不能使用==,编译器会报错

五、如何选择使用类还是结构

在代码中可以选择类或者结构来实现你所需要的代码块,完成相应的功能。但是结构实例传递的是值,而类实例传递的是引用。那么对于不同的任务,应该考虑到数据结构和功能的需求不同,从而选择不同的实例。

一般来说,下面的一个或多个条件满足时,应当选择创建一个结构:

1. 结构主要是用来封装一些简单的数据值

2. 当赋值或者传递的时候更希望这些封装的数据被赋值,而不是被引用过去

3. 所有被结构存储的属性本身也是数值类型

4. 结构不需要被另外一个类型继承或者完成其它行为

在其它情况下,类会是更好的选择。也就是说一般情况下,数据都会定义为类

六、集合类型的赋值和复制操作

和Objective-C不一样,Swift中,数组Array和字典Dictionary是用结构来实现的,下面我们来看看他们具体有什么不一样的地方

1. 字典的赋值和复制操作

var ages = ["Peter": 23, "Wei": 35, "Anish": 65, "Katya": 19]
var copiedAges = ages
ages["Wei"] = 0
println(ages)       //输出:[Anish: 65, Wei: 0, Peter: 23, Katya: 19]
println(copiedAges) //输出:[Anish: 65, Wei: 35, Peter: 23, Katya: 19]

由于字典是数值类型,赋值的时候会完整的赋值。

如果字典中的键值是数值类型(结构或者枚举),它们在赋值的时候会同时被复制。相反,如果是引用类型(类或者函数),引用本身将会被复制,而不是类实例或者函数本身。字典的这种复制方式和结构相同。

2. 数组的赋值和复制操作

和字典Dictionary类型比起来,数组Array的赋值和复制操作就更加复杂。Array类型和C语言中的类似,仅仅只会在需要的时候才会完整复制数组的值。

如果将一个数组赋值给一个常量或者变量,或者作为一个参数传递给函数,复制在赋值和函数调用的时候并不会发生。这两个数组将会共享一个元素序列,如果你修改了其中一个,另外一个也将会改变。

对于数组来说,复制只会在你进行了一个可能会修改数组长度操作时才会发生。包括拼接,添加或者移除元素等等。当复制实际发生的时候,才会像字典的赋值和复制操作一样。

var a = [1,2,3]
var b = a
a[0] = 5
println(a)  //输出:[5, 2, 3]
println(b)  //输出:[5, 2, 3]
a.append(4)
println(a)  //输出:[5, 2, 3, 4]
println(b)  //输出:[5, 2, 3]

如上面例子所示:

1. 在将b用a赋值,在仅改变数组中值,不改变长度的情况下,数组不会进行复制,b会随着a改变。

2. 在改变长度的情况下,会进行复制,b将是一个新的数组,不会随着a改变

3.
数组独立

在数组赋值时,如果不想两个变量公用一个数组,可以用unshare关键字来使数组独立。

var a = [1,2,3]
var b = a
a.unshare()
b[0] = 5
println(a)  //输出:[1, 2, 3]
println(b)  //输出:[5, 2, 3]

重点:

① 在调用a.unshare()方法时,会对a数组进行复制,然后让a指向复制数组。其他的指针还指向原对象

4. 判断2个数组是否指向同一数组地址

判断2个数组是否指向同一数组地址可以使用===和!==

var a = [1,2,3]
var b = a
if a === b{ }

注意:

如果对a或者b调用unshare之后。他们就不再指向同一数组地址了

5. 强制数组拷贝

如果想要将数组完整复制到一个新数组中,可以使用copy方法

var a = [1,2,3]
var b = a.copy()

注意:

①这时候a和b数组是2个不相关的数组,改变值不会对对方有任何影响

②如果你不确定你需要的数组是否是独立的,那么仅仅使用unshare就可以了。而copy方法不管当前是不是独立的,都会完整拷贝一次,哪怕这个数组已经是unshare的了。

Swift学习笔记:类和结构,布布扣,bubuko.com

时间: 2024-12-17 22:23:55

Swift学习笔记:类和结构的相关文章

Swift学习笔记(11)--类与结构体

类与结构是编程人员在代码中会经常用到的代码块.在类与结构中可以像定义常量,变量和函数一样,定义相关的属性和方法以此来实现各种功能. 和其它的编程语言不太相同的是,Swift不需要单独创建接口或者实现文件来使用类或者结构.Swift中的类或者结构可以在单文件中直接定义,一旦定义完成后,就能够被直接其它代码使用. 注意:一个类的实例一般被视作一个对象,但是在Swift中,类与结构更像是一个函数方法,在后续的章节中更多地是讲述类和结构的功能性. 1.类和结构的异同 类和结构有一些相似的地方,它们都可以

初探swift语言的学习笔记(类对象,函数)

swift扩展了很多功能和属性,有些也比较奇P.只有慢慢学习,通过经验慢慢总结了. 下面将初步学习一下类的写法. 码工,最大爱好就是看码,而不是文字,太枯燥. // // computer.swift // swiftDemo // // Created by apple on 14-6-8. // Copyright (c) 2014年 fengsh. All rights reserved. /* 写本例子的目的在于快速学习swift类的写法,包括知识点: 1.属性设置 2.构造.释构 3.

Swift语法学习之 类和结构体

类和结构体 本页包含内容: 类和结构体对比 结构体和枚举是值类型 类是引用类型 类和结构体的选择 集合(collection)类型的赋值与复制行为 与其他编程语言所不同的是,Swift 并不要求你为自定义类和结构去创建独立的接口和实现文件.你所要做的是在一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口. 注意: 通常一个类的实例被称为对象.然而在Swift 中,类和结构体的关系要比在其他语言中更加的密切,本章中所讨论的大部分功能都可以用在类和结构体上.因此,我们会主要使

Swift学习笔记十二:下标脚本(subscript)

下标脚本就是对一个东西通过索引,快速取值的一种语法,例如数组的a[0].这就是一个下标脚本.通过索引0来快速取值.在Swift中,我们可以对类(Class).结构体(structure)和枚举(enumeration)中自己定义下标脚本的语法 一.常规定义 class Student{ var scores:Int[] = Array(count:5,repeatedValue:0) subscript(index:Int) -> Int{ get{ return scores[index];

Swift学习笔记十:属性

1.存储属性       1. 作为特定类或结构实例的一部分,存储属性存储着常量或者变量的值.存储属性可分为变量存储属性(关键字var描述)和常量存储属性(关键字let描述). struct student{ let name = "" var score = 0 } let a = student(name:"小笨狼",score:96)           注意:                ① 定义储存属性时,需要为每一个属性定义一个默认值.在初始化的时候,

swift学习笔记(六)析构过程和使用闭包对属性进行默认值赋值

一.通过闭包和函数实现属性的默认值 当某个存储属性的默认值需要定制时,可以通过闭包或全局函数来为其提供定制的默认值. 注:全局函数结构体和枚举使用关键字static标注    函数则使用class关键字标注 当对一个属性使用闭包函数进行赋值时,每当此属性所述的类型被创建实例时,对应的闭包或函数会被调用,而他们的返回值会被作为属性的默认值. ESC: Class SomeCLass{ let someProperty:SomeType={ //给someProperty赋一个默认值 //返回一个与

Swift学习笔记(三):Protocols and Delegates

一.协议 | Protocols 协议用于定义完成某些功能所需要的方法和属性,协议本身并不提供这些功能的具体实现,只是用来描述这些实现.类.结构体.枚举通过提供协议所要求的方法.属性的具体实现来采用协议.能够满足协议要求的类型称之为协议的遵循者. 协议可以要求遵循者提供特定的实例属性.实例方法.类方法.操作符或下标脚本等. //创建一个协议,协议说声明了一个方法Speak protocol Speaker { func Speak() } //类Vicki遵循Speaker协议,在类中具体实现了

Swift学习笔记(15)--下标脚本(Subscripts)

下标脚本可以定义在类(Class).结构体(structure)和枚举(enumeration)这些目标中,使用中类似数组或者字典的用法 1.定义 定义下标脚本使用subscript关键字,语法: subscript(index: Int) -> Int { get { // 返回与入参匹配的Int类型的值 } set(newValue) { // 执行赋值操作 } } 注:newValue的类型必须和下标脚本定义的返回类型相同.与计算型属性相同的是set的入参声明newValue就算不写,在s

Swift学习笔记(14)--方法

1.分类 方法分为实例方法和类型方法 实例方法(Instance Methods):与java中的类似,略 类型方法(Type Methods):与java.oc中的类方法类似.声明类的类型方法,在方法的func关键字之前加上关键字class:声明结构体和枚举的类型方法,在方法的func关键字之前加上关键字static. 方法的参数名参见学习笔记的函数章节 2.在实例方法中修改值类型和self 结构体和枚举是值类型.一般情况下,值类型的属性不能在它的实例方法中被修改. 但是,如果你确实需要在某个