本文是學習《The Swift Programming Language》整理的相關隨筆,基本的語法不作介紹,主要介紹Swift中的一些特性或者與OC差異點。
系列文章:
比較類與結構體(Comparing Classes and Structures)
Classes and structures in Swift have many things in common. Both can:
- Define properties to store values
- Define methods to provide functionality
- Define subscripts to provide access to their values using subscript syntax
- Define initializers to set up their initial state
- Be extended to expand their functionality beyond a default implementation
- Conform to protocols to provide standard functionality of a certain kind
-
For more information, see Properties, Methods, Subscripts, Initialization, Extensions, and Protocols.
Classes have additional capabilities that structures do not:
- Inheritance enables one class to inherit the characteristics of another.
- Type casting enables you to check and interpret the type of a class instance at runtime.
- Deinitializers enable an instance of a class to free up any resources it has assigned.
- Reference counting allows more than one reference to a class instances
Swift 中類和結構體有很多共同點。共同處在于:
- 定義屬性用于存儲值
- 定義方法用于提供功能
- 定義附屬腳本用于訪問值
- 定義構造器用于生成初始化值
- 通過擴展以增加默認實現的功能
- 符合協議以對某類提供標準功能
與結構體相比,類還有如下的附加功能:
- 繼承允許一個類繼承另一個類的特征
- 類型轉換允許在運行時檢查和解釋一個類實例的類型
- 解構器允許一個類實例釋放任何其所被分配的資源
- 引用計數允許對一個類的多次引用
定義語法(Definition Syntax)
Classes and structures have a similar definition syntax.
You introduce classes with the class keyword and
structures with the struct keyword.
例子:
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
var someResolution = Resolution();
someResolution.width = 10;
someResolution.height = 10;
var someVideoMode = VideoMode();
someVideoMode.resolution = someResolution;
someVideoMode.frameRate = 1.0;
someVideoMode.name = "mp4";
print("someVideoMode.resolution: (\(someVideoMode.resolution.width) \(someVideoMode.resolution.height)),someVideoMode.name \(someVideoMode.name)");
執行結果:
someVideoMode.resolution: (10 10),someVideoMode.name Optional("mp4")
結構體與枚舉都是值類型數據(Structures and Enumerations Are Value Types)
A value type is a type whose value is copied when it is
assigned to a variable or constant, or when it is passed
to a function.
結構體例子:
struct Resolution {
var width = 0
var height = 0
}
let hd = Resolution(width:1920,height:1080)
var cinema = hd
cinema.width = 2048
print("cinema is now \(cinema.width) pixels wide")
print("hd is still \(hd.width) pixels wide")
執行結果:
cinema is now 2048 pixels wide
hd is still 1920 pixels wide
枚舉例子:
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
類是引用類型數據(Classes Are Reference Types)
Unlike value types, reference types are not copied when
they are assigned to a variable or constant, or when they
are passed to a function. Rather than a copy, a reference
to the same existing instance is used instead.
例子:
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
var someVideoMode = VideoMode();
someVideoMode.name = "mp4";
var otherVideoMode = someVideoMode;
otherVideoMode.name = "AVI"
print("someVideoMode.name : (\(someVideoMode.name)");
執行結果:
someVideoMode.name : (Optional("AVI")
恒等式操作符(Identity Operators)
It can sometimes be useful to find out if two constants or
variables refer to exactly the same instance of a class.
To enable this, Swift provides two identity operators:
Identical to (===)
Not identical to (!==)
接著上述的例子:
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
var someVideoMode = VideoMode();
someVideoMode.name = "mp4";
var otherVideoMode = someVideoMode;
otherVideoMode.name = "AVI"
var thirdVideoMode = VideoMode();
if someVideoMode === otherVideoMode{
print("someVideoMode === otherVideoMode")
}
if someVideoMode !== thirdVideoMode{
print("someVideoMode !== thirdVideoMode")
}
執行結果:
someVideoMode === otherVideoMode
someVideoMode !== thirdVideoMode
類和結構體的選擇(Choosing Between Classes and Structures)
You can use both classes and structures to define custom data types to use as the building blocks of your program’s
code.
However, structure instances are always passed by value,
and class instances are always passed by reference. This
means that they are suited to different kinds of tasks. As you consider the data constructs and functionality that
you need for a project, decide whether each data construct
should be defined as a class or as a structure.
As a general guideline, consider creating a structure when
one or more of these conditions apply:
- The structure’s primary purpose is to encapsulate a few
relatively simple data values.
- It is reasonable to expect that the encapsulated values
will be copied rather than referenced when you assign or
pass around an instance of that structure.
- Any properties stored by the structure are themselves
value types, which would also be expected to be copied rather than referenced.
- The structure does not need to inherit properties or behavior from another existing type.
Examples of good candidates for structures include:
- The size of a geometric shape, perhaps encapsulating a width property and a height property, both of type Double.
- A way to refer to ranges within a series, perhaps encapsulating a start property and a length property, both of type Int.
- A point in a 3D coordinate system, perhaps encapsulating x, y and z properties, each of type Double.
In all other cases, define a class, and create instances
of that class to be managed and passed by reference. In
practice, this means that most custom data constructs
should be classes, not structures.
按照通用的準則,當符合一條或多條以下條件時,請考慮構建結構體:
- 結構體的主要目的是用來封裝少量相關簡單數據值。
- 有理由預計一個結構體實例在賦值或傳遞時,封裝的數據將會被拷貝而不是被引用。
- 任何在結構體中儲存的值類型屬性,也將會被拷貝,而不是被引用。
- 結構體不需要去繼承另一個已存在類型的屬性或者行為。
合適的結構體候選者包括:
- 幾何形狀的大小,封裝一個width屬性和height屬性,兩者均為Double類型。
- 一定范圍內的路徑,封裝一個start屬性和length屬性,兩者均為Int類型。
- 三維坐標系內一點,封裝x,y和z屬性,三者均為Double類型。
字符串與集合類型的賦值和拷貝行為(Assignment and Copy Behavior for Strings, Arrays,and Dictionaries)
In Swift, many basic data types such as String, Array, and
Dictionary are implemented as structures. This means that
data such as strings, arrays, and dictionaries are copied
when they are assigned to a new constant or variable, or
when they are passed to a function or method.
- 在Swift中String,Array,Dictionary都是以結構體的方式實現的。因此當使用它們賦值或者傳入函數作為參數時都是以拷貝的方式傳入。
例子:
var array:[Int] = [1,2,3]
var otherArray = array
otherArray.append(4)
print("array:\(array),otherArray:\(otherArray)")
執行結果:
array:[1, 2, 3],otherArray:[1, 2, 3, 4]