Swift4 基礎部分: Classes and Structures

本文是學習《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]
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,250評論 4 61
  • 常量與變量使用let來聲明常量,使用var來聲明變量。聲明的同時賦值的話,編譯器會自動推斷類型。值永遠不會被隱式轉...
    莫_名閱讀 466評論 0 1
  • 簡單搭建監控系統 基礎環境: 安裝k2-compose 下載監控系統部署模版另存為k2-compose.yml,或...
    rm_rf閱讀 807評論 0 1
  • I:在表達稱贊時,如果能先描述所稱贊的具體內容,并且加上對方的稱謂或類似獨有信息的話,能讓對方感到獲得了特別的關注...
    幸福虛度的野人閱讀 256評論 0 2
  • 12月29日-12月30日 下面這段話是一位圈柚在圈圈三問中的提問,請你幫她梳理思路,概括出ta所表達的主題,來更...
    孫悟飯Y閱讀 262評論 0 1