Swift學習總結

數據類型


內置數據類型

Swift 提供了非常豐富的數據類型,以下列出了常用了集中數據類型:

Int

一般來說,你不需要專門指定整數的長度。Swift 提供了一個特殊的整數類型Int
,長度與當前平臺的原生字長相同:

  • 在32位平臺上,Int和Int32長度相同。
  • 在64位平臺上,Int和Int64長度相同。

除非你需要特定長度的整數,一般來說使用Int就夠了。這可以提高代碼一致性和可復用性。即使是在32位平臺上,Int可以存儲的整數范圍也可以達到-2,147,483,648~2,147,483,647,大多數時候這已經足夠大了。

UInt

Swift 也提供了一個特殊的無符號類型UInt,長度與當前平臺的原生字長相同:

  • 在32位平臺上,UInt和UInt32長度相同。
  • 在64位平臺上,UInt和UInt64長度相同。

注意:盡量不要使用UInt,除非你真的需要存儲一個和當前平臺原生字長相同的無符號整數。除了這種情況,最好使用Int,即使你要存儲的值已知是非負的。統一使用Int可以提高代碼的可復用性,避免不同類型數字之間的轉換,并且匹配數字的類型推斷,請參考類型安全和類型推斷

浮點數

浮點數是有小數部分的數字,比如3.14159,0.1和-273.15。
浮點類型比整數類型表示的范圍更大,可以存儲比Int
類型更大或者更小的數字。Swift 提供了兩種有符號浮點數類型:

  • Double表示64位浮點數。當你需要存儲很大或者很高精度的浮點數時請使用此類型。
  • Float表示32位浮點數。精度要求不高的話可以使用此類型。

注意:Double精確度很高,至少有15位數字,而Float最少只有6位數字。選擇哪個類型取決于你的代碼需要處理的值的范圍。

布爾值

Swift 有一個基本的布爾(Boolean)類型,叫做Bool。布爾值指邏輯上的值,因為它們只能是真或者假。Swift 有兩個布爾常量,true和false。

類型別名

類型別名對當前的類型定義了另一個名字,類型別名通過使用 typealias 關鍵字來定義。語法格式如下:

typealias Feet = Int
var distance: Feet = 100
print(distance)

類型推斷

當你要處理不同類型的值時,類型檢查可以幫你避免錯誤。然而,這并不是說你每次聲明常量和變量的時候都需要顯式指定類型。
如果你沒有顯式指定類型,Swift 會使用類型推斷(type inference)來選擇合適的類型。
當推斷浮點數的類型時,Swift 總是會選擇Double而不是Float。

可選類型


Swift 的可選(Optional)類型,用于處理值缺失的情況。可選表示"那兒有一個值,并且它等于 x "或者"那兒沒有值"。
Swfit語言定義后綴?作為命名類型Optional的簡寫,換句話說,以下兩種聲明是相等的:

var optionalInteger: Int?
var optionalInteger: Optional<Int>

當你聲明一個可選變量或者可選屬性的時候沒有提供初始值,它的值會默認為nil。
如果一個可選類型的實例包含一個值,你可以用后綴操作符 !使用操作符!去獲取值為nil的可選變量會有運行時錯誤

可選綁定

使用可選綁定(optional binding)來判斷可選類型是否包含值,如果包含就把值賦給一個臨時常量或者變量。可選綁定可以用在if和while語句中來對可選類型的值進行判斷并把值賦給一個常量或者變量。

var myString:String?
myString = "Hello, Swift!"
if let yourString = myString {
    print("你的字符串值為 - \(yourString)")
}  else  { 
    print("你的字符串沒有值")
}

運算符優先級


在一個表達式中可能包含多個有不同運算符連接起來的、具有不同數據類型的數據對象;由于表達式有多種運算,不同的運算順序可能得出不同結果甚至出現錯誤運算錯誤,因為當表達式中含多種運算時,必須按一定順序進行結合,才能保證運算的合理性和結果的正確性、唯一性。
優先級從上到下依次遞減,最上面具有最高的優先級,逗號操作符具有最低的優先級。
相同優先級中,按結合順序計算。大多數運算是從左至右計算,只有三個優先級是從右至左結合的,它們是單目運算符、條件運算符、賦值運算符。
基本的優先級需要記住:

  • 指針最優,單目運算優于雙目運算。如正負號。
  • 先乘除(模),后加減。
  • 先算術運算,后移位運算,最后位運算。請特別注意:1 << 3 + 2 & 7 等價于 (1 << (3 + 2))&7
  • 邏輯運算最后計算

函數


元組作為函數返回值

函數返回值類型可以是字符串,整型,浮點型等。
元組與數組類似,不同的是,元組中的元素可以是任意類型,使用的是圓括號。
你可以用元組(tuple)類型讓多個值作為一個復合值從函數中返回。
下面的這個例子中,定義了一個名為minMax(_:)的函數,作用是在一個Int數組中找出最小值與最大值。

func minMax(array: [Int]) -> (min: Int, max: Int)? {
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
}

前面的minMax(:)函數返回了一個包含兩個Int值的元組。但是函數不會對傳入的數組執行任何安全檢查,如果array參數是一個空數組,如上定義的minMax(:)在試圖訪問array[0]時會觸發一個運行時錯誤。
為了安全地處理這個"空數組"問題,將minMax(_:)函數改寫為使用可選元組返回類型,并且當數組為空時返回nil;

可變參數

可變參數可以接受零個或多個值。函數調用時,你可以用可變參數來指定函數參數,其數量是不確定的。
可變參數通過在變量類型名后面加入(...)的方式來定義。

func vari<N>(members: N...) {
    for i in members {
        print(i)
    }
}
vari(members: "Google", "Baidu", "Runoob")

閉包


閉包(Closures)是自包含的功能代碼塊,可以在代碼中使用或者用來作為參數傳值。
Swift 中的閉包與 C 和 Objective-C 中的代碼塊(blocks)以及其他一些編程語言中的 匿名函數比較相似。
全局函數和嵌套函數其實就是特殊的閉包。
Swift中的閉包有很多優化的地方:

  1. 根據上下文推斷參數和返回值類型
  2. 從單行表達式閉包中隱式返回(也就是閉包體只有一行代碼,可以省略return)
  3. 可以使用簡化參數名,如$0, $1(從0開始,表示第i個參數...)
  4. 提供了尾隨閉包語法(Trailing closure syntax)

sort函數

Swift 標準庫提供了名為sort的函數,會根據您提供的用于排序的閉包函數將已知類型數組中的值進行排序。
排序完成后,sort(:)方法會返回一個與原數組大小相同,包含同類型元素且元素已正確排序的新數組,原數組不會被sort(:)方法修改。
sort(_:)方法需要傳入兩個參數:

  • 已知類型的數組
  • 閉包函數,該閉包函數需要傳入與數組元素類型相同的兩個值,并返回一個布爾類型值來表明當排序結束后傳入的第一個參數排在第二個參數前面還是后面。如果第一個參數值出現在第二個參數值前面,排序閉包函數需要返回true,反之返回false。

尾隨閉包

尾隨閉包是一個書寫在函數括號之后的閉包表達式,函數支持將其作為最后一個參數調用。

func someFunctionThatTakesAClosure(closure: () -> Void) {
    // 函數體部分
}
// 以下是不使用尾隨閉包進行函數調用
someFunctionThatTakesAClosure(closure: {
    // 閉包主體部分
})
// 以下是使用尾隨閉包進行函數調用
someFunctionThatTakesAClosure() {
    // 閉包主體部分
}

枚舉


枚舉簡單的說也是一種數據類型,只不過是這種數據類型只包含自定義的特定數據,它是一組有共同特性的數據的集合。
Swift 的枚舉類似于 Objective C 和 C 的結構,枚舉的功能為:

  • 它聲明在類中,可以通過實例化類來訪問它的值。
  • 枚舉也可以定義構造函數(initializers)來提供一個初始成員值;可以在原始的實現基礎上擴展它們的功能。
  • 可以遵守協議(protocols)來提供標準的功能。
// 定義枚舉
enum DaysofaWeek {
    case Sunday
    case Monday
    case TUESDAY
    case WEDNESDAY
    case THURSDAY
    case FRIDAY
    case Saturday
}
var weekDay = DaysofaWeek.THURSDAY
weekDay = .THURSDAY
switch weekDay
{
case .Sunday:
    print("星期天")
case .Monday:
    print("星期一")
case .TUESDAY:
    print("星期二")
case .WEDNESDAY:
    print("星期三")
case .THURSDAY:
    print("星期四")
case .FRIDAY:
    print("星期五")
case .Saturday:
    print("星期六")
}

注意: 和 C 和 Objective-C 不同,Swift 的枚舉成員在被創建時不會被賦予一個默認的整型值。

枚舉相關值

以下實例中我們定義一個名為 Student 的枚舉類型,它可以是 Name 的一個相關值(Int,Int,Int,Int),或者是 Mark 的一個字符串類型(String)相關值。

enum Student {
    case Name(String)
    case Mark(Int,Int,Int)
}
var studDetails = Student.Name("Runoob")
var studMarks = Student.Mark(98,97,95)
switch studMarks {
case .Name(let studName):
    print("學生的名字是: \(studName)。")
case .Mark(let Mark1, let Mark2, let Mark3):
    print("學生的成績是: \(Mark1),\(Mark2),\(Mark3)。")
}

枚舉原始值

原始值可以是字符串,字符,或者任何整型值或浮點型值。每個原始值在它的枚舉聲明中必須是唯一的。
在原始值為整數的枚舉時,不需要顯式的為每一個成員賦值,Swift會自動為你賦值。
例如,當使用整數作為原始值時,隱式賦值的值依次遞增1。如果第一個值沒有被賦初值,將會被自動置為0。

enum Month: Int {
    case January = 1, February, March, April, May, June, July, August, September, October, November, December
}
let yearMonth = Month.May.rawValue
print("數字月份為: \(yearMonth)。")

屬性


計算屬性

類、結構體和枚舉可以定義計算屬性,計算屬性不直接存儲值,而是提供一個 getter 來獲取值,一個可選的 setter 來間接設置其他屬性或變量的值。

class sample {
    var no1 = 0.0, no2 = 0.0
    var length = 300.0, breadth = 150.0
    
    var middle: (Double, Double) {
        get{
            return (length / 2, breadth / 2)
        }
        set(axis){
            no1 = axis.0 - (length / 2)
            no2 = axis.1 - (breadth / 2)
        }
    }
}

var result = sample()
print(result.middle)

如果計算屬性的 setter 沒有定義表示新值的參數名,則可以使用默認名稱 newValue。

屬性觀察器

屬性觀察器監控和響應屬性值的變化,每次屬性被設置值的時候都會調用屬性觀察器,甚至新的值和現在的值相同的時候也不例外。
可以為除了延遲存儲屬性之外的其他存儲屬性添加屬性觀察器,也可以通過重載屬性的方式為繼承的屬性(包括存儲屬性和計算屬性)添加屬性觀察器。

注意:不需要為無法重載的計算屬性添加屬性觀察器,因為可以通過 setter 直接監控和響應值的變化。

可以為屬性添加如下的一個或全部觀察器:

  • willSet在設置新的值之前調用
  • didSet在新的值被設置之后立即調用
  • willSet和didSet觀察器在屬性初始化過程中不會被調用
class Samplepgm {
    var counter: Int = 0{
        willSet(newTotal){
            print("計數器: \(newTotal)")
        }
        didSet{
            if counter > oldValue {
                print("新增數 \(counter - oldValue)")
            }
        }
    }
}
let NewCounter = Samplepgm()

下標腳本


下標腳本語法及應用

語法

下標腳本允許你通過在實例后面的方括號中傳入一個或者多個的索引值來對實例進行訪問和賦值。
語法類似于實例方法和計算型屬性的混合。
與定義實例方法類似,定義下標腳本使用subscript關鍵字,顯式聲明入參(一個或多個)和返回類型。
與實例方法不同的是下標腳本可以設定為讀寫或只讀。這種方式又有點像計算型屬性的getter和setter:

subscript(index: Int) -> Int {
    get {
        // 用于下標腳本值的聲明
    }
    set(newValue) {
        // 執行賦值操作
    }
}

用法

根據使用場景不同下標腳本也具有不同的含義。
通常下標腳本是用來訪問集合(collection),列表(list)或序列(sequence)中元素的快捷方式。
你可以在你自己特定的類或結構體中自由的實現下標腳本來提供合適的功能。

下標腳本選項

下標腳本允許任意數量的入參索引,并且每個入參類型也沒有限制。
下標腳本的返回值也可以是任何類型。
下標腳本可以使用變量參數和可變參數。
一個類或結構體可以根據自身需要提供多個下標腳本實現,在定義下標腳本時通過傳入參數的類型進行區分,使用下標腳本時會自動匹配合適的下標腳本實現運行,這就是下標腳本的重載

struct Matrix {
    let rows: Int, columns: Int
    var print: [Double]
    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        print = Array(count: rows * columns, repeatedValue: 0.0)
    }
    subscript(row: Int, column: Int) -> Double {
        get {
            return print[(row * columns) + column]
        }
        set {
            print[(row * columns) + column] = newValue
        }
    }
}
// 創建了一個新的 3 行 3 列的Matrix實例
var mat = Matrix(rows: 3, columns: 3)

可選鏈


可選鏈(Optional Chaining)是一種是一種可以請求和調用屬性、方法和子腳本的過程,用于請求或調用的目標可能為nil。
可選鏈返回兩個值:

  • 如果目標有值,調用就會成功,返回該值
  • 如果目標為nil,調用將返回nil
    多次請求或調用可以被鏈接成一個鏈,如果任意一個節點為nil將導致整條鏈失效。

自動引用計數(ARC)


Swift 使用自動引用計數(ARC)這一機制來跟蹤和管理應用程序的內存
通常情況下我們不需要去手動釋放內存,因為 ARC 會在類的實例不再被使用時,自動釋放其占用的內存。
但在有些時候我們還是需要在代碼中實現內存管理。
ARC 功能

  • 當每次使用 init() 方法創建一個類的新的實例的時候,ARC 會分配一大塊內存用來儲存實例的信息。
  • 內存中會包含實例的類型信息,以及這個實例所有相關屬性的值。
  • 當實例不再被使用時,ARC 釋放實例所占用的內存,并讓釋放的內存能挪作他用。
  • 為了確保使用中的實例不會被銷毀,ARC 會跟蹤和計算每一個實例正在被多少屬性,常量和變量所引用。
  • 實例賦值給屬性、常量或變量,它們都會創建此實例的強引用,只要強引用還在,實例是不允許被銷毀的。

類實例之間的循環強引用

下面展示了一個不經意產生循環強引用的例子。例子定義了兩個類:Person和Apartment,用來建模公寓和它其中的居民:

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment?
    deinit { print("\(name) 被析構") }
}

class Apartment {
    let number: Int
    init(number: Int) { self.number = number }
    var tenant: Person?
    deinit { print("Apartment #\(number) 被析構") }
}

// 兩個變量都被初始化為nil
var runoob: Person?
var number73: Apartment?

// 賦值
runoob = Person(name: "Runoob")
number73 = Apartment(number: 73)

// 意感嘆號是用來展開和訪問可選變量 runoob 和 number73 中的實例
// 循環強引用被創建
runoob!.apartment = number73
number73!.tenant = runoob

// 斷開 runoob 和 number73 變量所持有的強引用時,引用計數并不會降為 0,實例也不會被 ARC 銷毀
// 注意,當你把這兩個變量設為nil時,沒有任何一個析構函數被調用。
// 強引用循環阻止了Person和Apartment類實例的銷毀,并在你的應用程序中造成了內存泄漏

Swift 提供了兩種辦法用來解決你在使用類的屬性時所遇到的循環強引用問題:

  • 弱引用
  • 無主引用

弱引用和無主引用允許循環引用中的一個實例引用另外一個實例而不保持強引用。這樣實例能夠互相引用而不產生循環強引用。
對于生命周期中會變為nil的實例使用弱引用。相反的,對于初始化賦值后再也不會被賦值為nil的實例,使用無主引用。

閉包引起的循環強引用

循環強引用還會發生在當你將一個閉包賦值給類實例的某個屬性,并且這個閉包體中又使用了實例。這個閉包體中可能訪問了實例的某個屬性,例如self.someProperty,或者閉包中調用了實例的某個方法,例如self.someMethod。這兩種情況都導致了閉包 "捕獲" self,從而產生了循環強引用。

class HTMLElement {
    
    let name: String
    let text: String?
    
    lazy var asHTML: () -> String = {
        [unowned self] in
        if let text = self.text {
            return "<\(self.name)>\(text)</\(self.name)>"
        } else {
            return "<\(self.name) />"
        }
    }
    
    init(name: String, text: String? = nil) {
        self.name = name
        self.text = text
    }
    
    deinit {
        print("\(name) 被析構")
    }
    
}

//創建并打印HTMLElement實例
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
print(paragraph!.asHTML())

// HTMLElement實例將會被銷毀,并能看到它的析構函數打印出的消息
paragraph = nil

HTMLElement 類產生了類實例和 asHTML 默認值的閉包之間的循環強引用。
實例的 asHTML 屬性持有閉包的強引用。但是,閉包在其閉包體內使用了self(引用了self.name和self.text),因此閉包捕獲了self,這意味著閉包又反過來持有了HTMLElement實例的強引用。這樣兩個對象就產生了循環強引用。
解決閉包引起的循環強引用:在定義閉包時同時定義捕獲列表作為閉包的一部分,通過這種方式可以解決閉包和類實例之間的循環強引用。

類型轉換


Swift 語言類型轉換可以判斷實例的類型。也可以用于檢測實例類型是否屬于其父類或者子類的實例。
Swift 中類型轉換使用 is 和 as 操作符實現,is 用于檢測值的類型,as 用于轉換類型。
類型轉換也可以用來檢查一個類是否實現了某個協議。

檢查類型

類型檢查使用 is 關鍵字。
操作符 is 來檢查一個實例是否屬于特定子類型。若實例屬于那個子類型,類型檢查操作符返回 true,否則返回 false。

向下轉型

向下轉型,用類型轉換操作符(as? 或 as!)
當你不確定向下轉型可以成功時,用類型轉換的條件形式(as?)。條件形式的類型轉換總是返回一個可選值(optional value),并且若下轉是不可能的,可選值將是 nil。
只有你可以確定向下轉型一定會成功時,才使用強制形式(as!)。當你試圖向下轉型為一個不正確的類型時,強制形式的類型轉換會觸發一個運行時錯誤。

Any和AnyObject的類型轉換

Swift為不確定類型提供了兩種特殊類型別名:
AnyObject可以代表任何class類型的實例。
Any可以表示任何類型,包括方法類型(function types)。

注意:只有當你明確的需要它的行為和功能時才使用Any和AnyObject。在你的代碼里使用你期望的明確的類型總是更好的。

擴展


擴展就是向一個已有的類、結構體或枚舉類型添加新功能。
擴展可以對一個類型添加新的功能,但是不能重寫已有的功能。
Swift 中的擴展可以:

  • 添加計算型屬性和計算型靜態屬性
  • 定義實例方法和類型方法
  • 提供新的構造器
  • 定義下標
  • 定義和使用新的嵌套類型
  • 使一個已有類型符合某個協議

協議


協議規定了用來實現某一特定功能所必需的方法和屬性。
任意能夠滿足協議要求的類型被稱為遵循(conform)這個協議。
類,結構體或枚舉類型都可以遵循協議,并提供具體實現來完成協議定義的方法和功能。

協議構造器規定在類中的實現

你可以在遵循該協議的類中實現構造器,并指定其為類的指定構造器或者便利構造器。在這兩種情況下,你都必須給構造器實現標上"required"修飾符:

class SomeClass: SomeProtocol {
    required init(someParameter: Int) {
        // 構造器實現
    }
}

protocol tcpprotocol {
    init(aprot: Int)
}

class tcpClass: tcpprotocol {
    required init(aprot: Int) {
    }
}

使用required修飾符可以保證:所有的遵循該協議的子類,同樣能為構造器規定提供一個顯式的實現或繼承實現。
如果一個子類重寫了父類的指定構造器,并且該構造器遵循了某個協議的規定,那么該構造器的實現需要被同時標示required和override修飾符:

// 因為遵循協議,需要加上"required"; 因為繼承自父類,需要加上"override" 
required override convenience init(no1: Int) { 
    self.init(no1:no1, no2:0) 
}

協議類型

盡管協議本身并不實現任何功能,但是協議可以被當做類型來使用。
協議可以像其他普通類型一樣使用,使用場景:

  • 作為函數、方法或構造器中的參數類型或返回值類型
  • 作為常量、變量或屬性的類型
  • 作為數組、字典或其他容器中的元素類型

類專屬協議

你可以在協議的繼承列表中,通過添加class關鍵字,限制協議只能適配到類(class)類型。
該class關鍵字必須是第一個出現在協議的繼承列表中,其后,才是其他繼承協議。格式如下:

protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol { 
    // 協議定義
}

協議合成

Swift 支持合成多個協議,這在我們需要同時遵循多個協議時非常有用。
語法格式如下:
protocol<SomeProtocol, AnotherProtocol>

檢驗協議的一致性

你可以使用is和as操作符來檢查是否遵循某一協議或強制轉化為某一類型。

  • is操作符用來檢查實例是否遵循了某個協議。
  • as?返回一個可選值,當實例遵循協議時,返回該協議類型;否則返回nil。
  • as用以強制向下轉型,如果強轉失敗,會引起運行時錯誤。

泛型


Swift 提供了泛型讓你寫出靈活且可重用的函數和類型。
Swift 標準庫是通過泛型代碼構建出來的。
Swift 的數組和字典類型都是泛型集。
你可以創建一個Int數組,也可創建一個String數組,或者甚至于可以是任何其他 Swift 的類型數據數組。
泛型函數可以訪問任何類型,如 Int 或 String。
以下實例是一個泛型函數 exchange 用來交換兩個 Int 和 String 值:

func exchange<T>( a: inout T, b: inout T) {
    let temp = a
    a = b
    b = temp
}

這個函數的泛型版本使用了占位類型名字(通常此情況下用字母T來表示)來代替實際類型名(如Int、String或Double)。占位類型名沒有提示T必須是什么類型,但是它提示了a和b必須是同一類型T,而不管T表示什么類型。只有 exchange(::)函數在每次調用時所傳入的實際類型才能決定T所代表的類型。
另外一個不同之處在于這個泛型函數名后面跟著的占位類型名字(T)是用尖括號括起來的()。這個尖括號告訴 Swift 那個T是 exchange(::)函數所定義的一個類型。因為T是一個占位命名類型,Swift 不會去查找命名為T的實際類型。

Where 語句

類型約束能夠確保類型符合泛型函數或類的定義約束。
你可以在參數列表中通過where語句定義參數的約束。
你可以寫一個where語句,緊跟在在類型參數列表后面,where語句后跟一個或者多個針對關聯類型的約束,以及(或)一個或多個類型和關聯類型間的等價(equality)關系。
實例
下面的例子定義了一個名為allItemsMatch的泛型函數,用來檢查兩個Container實例是否包含相同順序的相同元素。
如果所有的元素能夠匹配,那么返回一個為true的Boolean值,反之則為false。

protocol Container {
    associatedtype ItemType
    mutating func append(item: ItemType)
    var count: Int { get }
    subscript(i: Int) -> ItemType { get }
}

struct Stack<T>: Container {
    // original Stack<T> implementation
    var items = [T]()
    mutating func push(item: T) {
        items.append(item)
    }
    
    mutating func pop() -> T {
        return items.removeLast()
    }
    
    // conformance to the Container protocol
    mutating func append(item: T) {
        self.push(item: item)
    }
    
    var count: Int {
        return items.count
    }
    
    subscript(i: Int) -> T {
        return items[i]
    }
}

func allItemsMatch<C1: Container, C2: Container where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
    (someContainer: C1, anotherContainer: C2) -> Bool {
    // 檢查兩個Container的元素個數是否相同
    if someContainer.count != anotherContainer.count {
        return false
    }
    
    // 檢查兩個Container相應位置的元素彼此是否相等
    for i in 0..<someContainer.count {
        if someContainer[i] != anotherContainer[i] {
            return false
        }
    }
    // 匹配所有項,返回 true
    return true
}

訪問控制


訪問控制可以限定其他源文件或模塊中代碼對你代碼的訪問級別。
你可以明確地給單個類型(類、結構體、枚舉)設置訪問級別,也可以給這些類型的屬性、函數、初始化方法、基本類型、下標索引等設置訪問級別。
協議也可以被限定在一定的范圍內使用,包括協議里的全局常量、變量和函數。
訪問控制基于模塊與源文件。
模塊指的是以獨立單元構建和發布的Framework或Application。在Swift 中的一個模塊可以使用import關鍵字引入另外一個模塊。
源文件是單個源碼文件,它通常屬于一個模塊, 源文件可以包含多個類和函數 的定義。
Swift 為代碼中的實體提供了三種不同的訪問級別:public、internal、private。

  • Public:可以訪問自己模塊中源文件里的任何實體,別人也可以通過引入該模塊來訪問源文件里的所有實體。
  • Internal:可以訪問自己模塊中源文件里的任何實體,但是別人不能訪問該模塊中源文件里的實體。
  • Private:只能在當前源文件中使用的實體,稱為私有實體。

public為最高級訪問級別,private為最低級訪問級別。

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

推薦閱讀更多精彩內容