内容来源
结构体和类
Swift 并不要求你为自定义的结构体和类的接口与实现代码分别创建文件。你只需在单一的文件中定义一个结构体或者类,系统将会自动生成面向其它代码的外部接口。
所有结构体都有一个自动生成的成员逐一构造器,用于初始化新结构体实例中成员的属性。新实例中各个属性的初始值可以通过属性的名称传递到成员逐一构造器之中:
结构体和枚举是值类型。当它被赋值给一个变量、常量或者被传递给一个函数的时候,其值会被拷贝。后者与原值脱钩。
Swift 中所有的基本类型:整数(integer)、浮点数(floating-point number)、布尔值(boolean)、字符串(string)、数组(array)和字典(dictionary),都是值类型,其底层也是使用结构体实现的。
结构体与类看起来写法相似,但有着本质的不同。结构体是值类型。类是指针类型。
相同(===)表示两个类类型(class type)的常量或者变量引用同一个类实例。
不相同(!==)
属性
属性将值与特定的类、结构体或枚举关联。存储属性会将常量和变量存储为实例的一部分,而计算属性则是直接计算(而不是存储)值。计算属性可以用于类、结构体和枚举,而存储属性只能用于类和结构体。
?存储属性就是一般的有值的属性。计算属性只计算,类似于方法??
可以利用属性包装器来复用多个属性的 getter 和 setter 中的代码。
?属性包装器??是一种方法。包含若干个属性的getter和setter方法。
如果创建了一个结构体实例并将其赋值给一个常量,则无法修改该实例的任何属性,即使被声明为可变属性也不行。结构体负值给常量,则固定。
这种行为是由于结构体属于值类型。当值类型的实例被声明为常量的时候,它的所有属性也就成了常量。
对应的,类如果是常量类型会怎样?属于引用类型的类则不一样。把一个引用类型的实例赋给一个常量后,依然可以修改该实例的可变属性。
延时加载存储属性
延时加载存储属性是指当第一次被调用的时候才会计算其初始值的属性。在属性声明前使用 lazy 来标示一个延时加载存储属性。
延时加载必须是var类型属性。
因为属性的初始值可能在实例构造完成之后才会得到。而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延时加载。
延时加载存储属性可以避免复杂类中不必要的初始化工作。
隐式返回的函数
如果一个函数的整个函数体是一个单行表达式,这个函数可以隐式地返回这个表达式。
震惊,不得不说,Swift的灵活性比Object 高很多。
可变参数
一个可变参数(variadic parameter)可以接受零个或多个值。函数调用时,你可以用可变参数来指定函数参数可以被传入不确定数量的输入值。通过在变量类型名后面加入(...)的方式来定义可变参数。
可变参数的传入值在函数体中变为此类型的一个数组
?既然可以认为参数变成了数组,那为何不直接用数组呢?看起来没有方便多少。
存储型属性的值不能处于一个未知的状态。
你可以在构造器(init)中为存储型属性设置初始值,也可以在定义属性时分配默认值。
当你为存储型属性分配默认值或者在构造器中为设置初始值时,它们的值是被直接设置的,不会触发任何属性观察者。
无论是默认构造器还是自定义构造器,都是init方法。属性设置默认值比在构造器里设置要好。如果结构体或类为所有属性提供了默认值,又没有提供任何自定义的构造器,那么 Swift 会给这些结构体或类提供一个默认构造器。这个默认构造器将简单地创建一个所有属性值都设置为它们默认值的实例。
结构体如果没有定义任何自定义构造器,它们将自动获得一个逐一成员构造器
类的继承和构造过程
指定构造器是类中最主要的构造器。一个指定构造器将初始化类中提供的所有属性,并调用合适的父类构造器让构造过程沿着父类链继续往上进行。
指定构造器
init(parameters) {
statements
}
便利构造器语法
convenience init(parameters) {
statements
}
规则 1: 指定构造器必须调用其直接父类的的指定构造器。
规则 2:便利构造器必须调用同类中定义的其它构造器。
规则 3:便利构造器最后必须调用指定构造器。
对于类的实例来说,它的常量属性只能在定义它的类的构造过程中修改;不能在子类中修改。
网友评论