类和结构体对比、结构体和枚举是值类型、类是引用类型、类和结构体的选择、字符串,数组和字典类型的赋值与复制行为。
Swift并不要求为自定义类和结构去创建独立的接口和实现文件。所要做的是在一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口。
类和结构体对比:
共同之处:
定义属性用于存储值
定义方法用于提供功能
定义下标操作使得可以通过下标语法来访问实例所包含的值
定义构造器用于生成初始化值
通过扩展以增加默认实现的功能
实现协议以提供某种标准功能
与结构体相比,类还有如下的附加功能:
继承允许一个类继承另一个类的特征
类型转换允许在运行时检查和解释一个类实例的类型
析构器允许一个类实例释放任何其所被分配的资源
引用计数允许对一个类的多次引用
注意:结构体总是通过被复制的方式在代码中传递,不使用引用计数。
定义语法:
类和结构体有着类似的定义方式。通过关键字class和struct来分别表示类和结构体,并在一对大括号中定义它们的具体内容。
class SomeClass{
//...
}
struct SomeStruct{
//...
}
注意:在每次定义一个新类或者结构体的时候,实际上是定义了一个新的Swift类型。
(Swift中类型名称风格一般是大写字母开头)
存储属性是被捆绑和存储在类或结构体中的常量或变量。
class aa{
var b:Int=8
var c=1.9
var d:String?
}
类的存储属性在实例化对象时必须有值。
类和结构体实例:
var t=a()
最简单的构造形式是在结构体或类的类型名称后跟最一对空括号,所创建的类或结构体实例的属性均会被初始化为默认值。
属性访问:
通过点语法,可以访问实例的属性。
print(a.b)
也可以通过点语法为变量属性赋值。
Swift允许直接设置类或结构体属性的子属性(如变量存储属性)。而不用将整个实例更换1.
结构体类型的成员逐一构造器:
所有结构体都有一个自动生成的成员逐一构造器,用于初始化新结构体实例中成员的属性。新实例中各个属性的初始值可以通过属性的名称传递到成员逐一构造器中。
struct bb{
var a=9
}
var tb=bb(a:8) //将tb.a构造时设置为8
类实例没有默认的成员逐一构造器。
结构体和枚举是值类型:
值类型被赋予给一个变量、常量或者被传递给一个函数的时候,其值会被拷贝。
Swift中,所有的基本类型:整数、浮点数、布尔值、字符串、数组和字典,都是值类型,并且在底层都是以结构体的形式实现。
结构体和枚举类型都是值类型,它们的实例,以及实例中所包含的任何值类型属性,在代码中传递的时候都会被复制。
类是引用类型:
与值类型不同,引用类型在被赋予到一个变量、常量或者被传递到一个函数时,其值不会被拷贝。因此,引用的是已存在的实例本身而不是其拷贝。
恒等运算符:
因为类是引用类型,有可能有多个常量和变量在幕后同时被引用到同一个类实例。(对于结构体和枚举来说,值类型不存在这个问题)
如果能够判断两个常量或者变量是否引用同一个类实例将会很有帮助。Swift内建了两个恒等运算符:
等价于(===)
不等价于(!==)
运用这两个运算符检测两个常量或变量是否引用同一个实例。
等价于===表示两个类类型的常量或者变量引用同一个类实例。(等于==表示值相等)
不等价于!==表示两个类类型的常量或者变量不引用同一个实例。(不等于!=表示值不相等)
Swift中的引用类型与C/C++/OC中的指针类似,引用类型的变量和常量即指向了某个实例的地址,但不需要使用*操作符,也不能解引用。
类和结构体的选择:
主要基于是采用值类型还是引用类型传递。
结构体较简单、类适合复杂的有继承关系的情况。大部分情况使用类。
字符串、数组、和字典类型的赋值与复制行为:
String、Array和Dictionary类型均以结构体的形式实现。这意味着被赋值给新的变量或常量,或者被传入函数或方法中时,它们的值会被拷贝。
(然而Swift在幕后只在绝对必要时才执行实际的拷贝。Swift管理所有的值拷贝以确保性能最优化,所以没必要去回避赋值来保证性能最优化)