Swift 的全域變數、局部變數與類型屬性

來源:互聯網
上載者:User

標籤:android   swift   objective-c   

全域變數和局部變數

計算屬性和屬性監視器所描述的模式也可以用於全域變數和局部變數,全域變數是在函數、方法、閉包或任何類型之外定義的變數,局部變數是在函數、方法或閉包內部定義的變數。

 

前面章節提到的全域或局部變數都屬於儲存型變數,跟儲存屬性類似,它提供特定類型的儲存空間,並允許讀取和寫入。

 

另外,在全域或局部範圍都可以定義計算型變數和為儲存型變數定義監視器,計算型變數跟計算屬性一樣,返回一個計算的值而不是儲存值,聲明格式也完全一樣。

 

注意:

 

全域的常量或變數都是延遲計算的,跟延遲儲存屬性相似,不同的地方在於,全域的常量或變數不需要標記@lazy特性。

 

局部範圍的常量或變數不會延遲計算。

 

類型屬性

執行個體的屬性屬於一個特定類型執行個體,每次類型執行個體化後都擁有自己的一套屬性值,執行個體之間的屬性相互獨立。

 

也可以為類型本身定義屬性,不管類型有多少個執行個體,這些屬性都只有唯一一份。這種屬性就是類型屬性。

 

類型屬性用於定義特定類型所有執行個體共用的資料,比如所有執行個體都能用的一個常量(就像 C 語言中的靜態常量),或者所有執行個體都能訪問的一個變數(就像 C 語言中的靜態變數)。

 

對於值類型(指結構體和枚舉)可以定義儲存型和計算型類型屬性,對於類(class)則只能定義計算型類型屬性。

 

值類型的儲存型類型屬性可以是變數或常量,計算型類型屬性跟執行個體的計算屬性一樣定義成變數屬性。

 

注意:

 

跟執行個體的儲存屬性不同,必須給儲存型類型屬性指定預設值,因為類型本身無法在初始化過程中使用構造器給類型屬性賦值。

 

類型屬性文法

在 C 或 Objective-C 中,靜態常量和靜態變數的定義是通過特定類型加上global關鍵字。在 Swift 程式設計語言中,類型屬性是作為類型定義的一部分寫在類型最外層的花括弧內,因此它的作用範圍也就在類型支援的範圍內。

 

使用關鍵字static來定義值類型的類型屬性,關鍵字class來為類(class)定義類型屬性。下面的例子示範了儲存型和計算型類型屬性的文法:

 

struct SomeStructure {   static var storedTypeProperty = "Some value."   static var computedTypeProperty: Int {   // 這裡返回一個 Int 值    }}enum SomeEnumeration {   static var storedTypeProperty = "Some value."   static var computedTypeProperty: Int {   // 這裡返回一個 Int 值    }}class SomeClass {   class var computedTypeProperty: Int {   // 這裡返回一個 Int 值    }}


注意:

 

例子中的計算型類型屬性是唯讀,但也可以定義可讀可寫的計算型類型屬性,跟執行個體計算屬性的文法類似。

 

擷取和設定類型屬性的值

跟執行個體的屬性一樣,類型屬性的訪問也是通過點運算子來進行,但是,類型屬性是通過類型本身來擷取和設定,而不是通過執行個體。比如:

 

println(SomeClass.computedTypeProperty)// 輸出 "42" println(SomeStructure.storedTypeProperty)// 輸出 "Somevalue."SomeStructure.storedTypeProperty ="Another value."println(SomeStructure.storedTypeProperty)// 輸出 "Anothervalue.”


下面的例子定義了一個結構體,使用兩個儲存型類型屬性來表示多個聲道的聲音電平值,每個聲道有一個 0 到 10 之間的整數表示聲音電平值。

 

後面的圖表展示了如何聯合使用兩個聲道來表示一個立體聲的聲音電平值。當聲道的電平值是 0,沒有一個燈會亮;當聲道的電平值是 10,所有燈點亮。本圖中,左聲道的電平是 9,右聲道的電平是 7。

 

 

 

上面所描述的聲道模型使用AudioChannel結構體來表示:

 

struct AudioChannel {   static let thresholdLevel = 10   static var maxInputLevelForAllChannels = 0   var currentLevel: Int = 0 {   didSet {       if currentLevel > AudioChannel.thresholdLevel {           // 將新電平值設定為閥值           currentLevel = AudioChannel.thresholdLevel       }       if currentLevel > AudioChannel.maxInputLevelForAllChannels {           // 儲存當前電平值作為新的最大輸入電平           AudioChannel.maxInputLevelForAllChannels = currentLevel       }    }    }}


結構AudioChannel定義了 2 個儲存型類型屬性來實現上述功能。第一個是thresholdLevel,表示聲音電平的最大上限閾值,它是一個取值為 10 的常量,對所有執行個體都可見,如果聲音電平高於 10,則取最大上限值 10(見後面描述)。

 

第二個類型屬性是變數儲存型屬性maxInputLevelForAllChannels,它用來表示所有AudioChannel執行個體的電平值的最大值,初始值是 0。

 

AudioChannel也定義了一個名為currentLevel的執行個體儲存屬性,表示當前聲道現在的電平值,取值為 0 到 10。

 

屬性currentLevel包含didSet屬性監視器來檢查每次新設定後的屬性值,有如下兩個檢查:

 

如果currentLevel的新值大於允許的閾值thresholdLevel,屬性監視器將currentLevel的值限定為閾值thresholdLevel。

如果修正後的currentLevel值大於任何之前任意AudioChannel執行個體中的值,屬性監視器將新值儲存在靜態屬性maxInputLevelForAllChannels中。

注意:

 

在第一個檢查過程中,didSet屬性監視器將currentLevel設定成了不同的值,但這時不會再次調用屬性監視器。

可以使用結構體AudioChannel來建立表示立體聲系統的兩個聲道leftChannel和rightChannel:

 

var leftChannel = AudioChannel()var rightChannel = AudioChannel()


如果將左聲道的電平設定成 7,類型屬性maxInputLevelForAllChannels也會更新成 7:

 

leftChannel.currentLevel = 7println(leftChannel.currentLevel)// 輸出 "7"println(AudioChannel.maxInputLevelForAllChannels)// 輸出 "7"如果試圖將右聲道的電平設定成 11,則會將右聲道的currentLevel修正到最大值 10,同時maxInputLevelForAllChannels的值也會更新到 10: rightChannel.currentLevel = 11println(rightChannel.currentLevel)// 輸出 "10"println(AudioChannel.maxInputLevelForAllChannels)// 輸出 "10"


Swift 的全域變數、局部變數與類型屬性

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.