中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Swift編程高級教程 變量與常量

發布時間:2020-07-11 15:04:07 來源:網絡 閱讀:604 作者:wcrane 欄目:移動開發

常量與變量

常量和變量是某個特定類型的值的名字,如果在程序運行時值不能被修改的是一個常量,反之是一個變量。

一、常量和變量的聲明

Swift中的常量和變量在使用前必須先聲明。其中let關鍵字聲明常量,var關鍵字聲明變量:

//聲明一個名為maximumNumberOfLoginAttempts的整型常量,并且值為10let maximumNumberOfLoginAttempts = 10//聲明一個名為currentLoginAttempt的整型變量,并且值為0var currentLoginAttempt = 0

可以在同一行聲明多個變量,中間用逗號,隔開:

var x = 0.0, y = 0.0, z = 0.0

提示
如果在程序運行的時候值不需要發生改變,應該將它們聲明為常量,否則聲明為變量

變量的值可以進行修改:

var friendlyWelcome = "Hello!"friendlyWelcome = "Bonjour!" //friendlyWelcome的值發生改變

常量的值一旦設置后就不能在修改:

let languageName = "Swift"languageName = "Swift++" //編譯時出錯
類型說明

在Swift中聲明常量或者變量可以在后面用冒號:指定它們的數據類型。

//聲明一個String類型的變量,可以存放String類型的值var welcomeMessage: String

提示
實際應用中很少需要指定變量數據類型,Swift會根據所設置的值的類型進行推導。

命名規則

Swift中可以使用任意字符給常量和變量命名,包括Unicode編碼,比如中文、Emoji等:

let π = 3.14159let 你好 = "你好世界"let dog = "dogcow"

名字里面不能包含數學運算符、箭頭、非法的Unicode字符以及不能識別的字符等,并且不能以數字開頭。同一個作用域的變量或者常量不能同名。

提示
如果想用關鍵字作為變量的名字,要用(`)包裹起來。為了方便理解,如果不是萬不得已,不應該使用關鍵字作為變量的名字。

打印變量的值

println函數可以打印常量或者變量的值:

println(friendlyWelcome) //打印出“Bonjour!”

println是一個全局函數,輸出時自動在結尾添加換行。print函數與它的功能類似,只是不會在結尾添加換行符。printlnNSLog類似,可以用來輸出復雜的日志信息。Swift使用字符串插值來輸出變量和常量。

println("The current value of friendlyWelcome is \(friendlyWelcome)")//打印“The current value of friendlyWelcome is Bonjour!”
注釋

注釋是用來幫助理解和記憶代碼功能的,并不會參與編譯。Swift有兩種注釋形式,單行注釋和多行注釋:

//這是單行注釋,用兩個斜線開頭,直到改行的結尾/*這是多行注釋,
可以橫跨很多行,
/*比C語言更加NB的是,*/它竟然還支持嵌套的注釋!*/
分號

Swift中語句結尾的分號;不是必須的,不過如果想要在同一行中寫多個語句,則需要使用;進行分隔。

let cat = "cat"; println(cat)//打印“cat”

二、屬性

屬性是依賴于某個特定的類、結構體或者枚舉類型的值。Swift有兩種屬性:存儲類型和計算類型。其中存儲類型可以作為實例的一部分存放變量或者常量的值,而計算類型的屬性值是通過運算的來的。計算類型的屬性可以在類、結構體和枚舉類型中出現,但存儲類型只可能出現在類和結構體類型中。

屬性一般依賴于一個特定類型的實例,但是也可以依賴于類本身。依賴于類型本身的屬性稱為類型屬性。

可以定義屬性觀察者來監督屬性值的改變,從而作出響應。

存儲屬性

常量屬性let的值在初始化后不能在改變,而變量屬性var的值可以隨時更改。

struct FixedLengthRange {    var firstValue: Int
    let length: Int
}var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
rangeOfThreeItems.firstValue = 6
結構體常量的存儲屬性

如果一個結構體實例被賦值給一個常量,則這個實例所擁有的存儲類型的屬性都不能在改變,包括變量屬性在內。

let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
rangeOfFourItems.firstValue = 6//編譯錯誤,firstValue的值不能改變
延時存儲屬性

延時存儲屬性的初始值直到第一次使用的時候才進行計算,在聲明時通過@lazy進行標記。

提示
一定要將延時存儲屬性聲明為變量(var),因為它的初始值可能會在實例初始化完成后才有,而常量屬性一般在實例初始化完成之前就會有值。

當屬性的初始值依賴于外部銀子,并且該因子的值在實例初始化完成之前不確定時,延時屬性非常有用。如果屬性初始化時需要進行大量的計算,也可以考慮使用延時屬性。

下面是延時屬性的示例:

class DataImporter {    /*
    DataImporter是一個從外部文件導入數據的類。假設它需要花費較多的時間進行初始化
    */
    var fileName = "data.txt"
    //DataImporter類的數據導入功能}

class DataManager {
    @lazy var importer = DataImporter()    var data = String[]()    //DataManager類提供數據管理功能}

let manager = DataManager()
manager.data += "Some data"manager.data += "Some more data"http://DataImporter實例還沒有創建

只有訪問DataManagerimporter屬性時才會去創建這個對象。

println(manager.importer.filename)//創建importer屬性并打印“data.txt"
存儲屬性與實例變量

Objective-C類的對象可以使用屬性或者實例變量來存儲值。Swift中并沒有所謂的實例變量,而是將它們統一為屬性了,這樣使得屬性的聲明更加簡化。

計算屬性

除了存儲屬性外,類、結構體和枚舉類型還可以定義計算屬性。這些計算屬性并不能夠存儲值,而是通過getter方法和可選的setter方法來間接的獲取和設置其它屬性和值。

struct Point {    var x = 0.0, y = 0.0}struct Size {    var width = 0.0, height = 0.0}struct Rect {    var origin = Point()    var size = Size()    var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)            return Point(x: centerX, y: centerY)
        }

        set(newCenter) {
            origin.x = newCenter.x - (size.width / 2)
            origin.y = newCenter.y - (size.height / 2)
        }
    }
}var square = Rect(origin: Point(x: 0.0, y: 0.0),
                    size: Size(width: 10.0, height: 10.0))
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y: 15.0)println("square.origin is now at (\(square.origin.x), \(square.origin.y))")//打印”square.origin is now at (10.0, 10.0)“

這個例子定義了三個結構體來表示幾何形狀:

  • Point封裝了(x, y)坐標。

  • Size封裝了寬度和高度。

  • Rect用坐標原點和大小定義一個矩形。

其中Rect結構體還提供了一個center的計算屬性。這個屬性的值是由矩形的originsize屬性決定的,它本身并不需要存儲信息。但是改變center的值,會間接的修改矩形的其它屬性。
Swift編程高級教程 變量與常量

三、簡化setter的聲明

如果沒有為計算屬性的setter的新值指定名字,則默認使用newValue。下面是Rect結構體的另外一種寫法:

struct AlternativeRect {    var origin = Point()    var size = Size()    var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)            return Point(x: centerX, y: centerY)
        }
        set {
            origin.x = newValue.x - (size.width / 2)
            origin.y = newValue.y - (size.height / 2)
        }
    }
}
只讀的計算屬性

如果一個計算屬性只有getter而沒有聲明setter,則它是一個只讀的計算屬性。只讀屬性只能通過點語法返回一個值,而不能對它進行設置。

提示
必須使用var 聲明計算屬性,包括只讀的計算屬性在內,因為它們的值是可能改變的。而let只能用于常量的聲明,表示它們的值不能發生改變。

還可以省略只讀計算屬性聲明中的get關鍵字。

struct Cuboid {    var width = 0.0, height = 0.0, depth = 0.0
    var volume: Double {        return width * height * depth
    }
}

let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)println("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")//打印“the volume of fourByFiveByTwo is 40.0”
屬性觀察者

屬性觀察者用來觀察和響應屬性值的變化。每次設置屬性的值都會調用相應的觀察者,哪怕是設置相同的值。

可以給除延時存儲屬性以外的任何存儲屬性添加觀察者。通過重寫屬性,可以在子類中給父類的屬性(包括存儲屬性和計算屬性)添加觀察者。

提示
不需要給類本身定義的計算屬性添加觀察者,完全可以在計算屬性的setter中完成對值的觀察。

通過下面兩個方法對屬性進行觀察:

  • willSet在屬性的值發生改變之前調用。

  • didSet在設置完屬性的值后調用。

如果沒有給willSet指定參數的話,編譯器默認提供一個newValue做為參數。同樣,在didSet中如果沒有提供參數的話,默認為oldValue

提示
willSetdidSet觀察者在屬性進行初始化的時候不會被調用。

class StepCounter {    var totalSteps: Int = 0 {
        willSet(newTotalSteps) {            println("About to set totalSteps to \(newTotalSteps)")
        }
        didSet {            if totalSteps > oldValue {                println("Added \(totalSteps - oldValue) steps")
            }
        }
    }
}

let stepCounter = StepCounter()
stepCounter.totalSteps = 200//About to set totalSteps to 200//Added 200 stepsstepCounter.totalSteps = 360//About to set totalSteps to 360//Added 160 stepsstepCounter.totalSteps = 896//About to set totalSteps to 896//Added 536 steps

提示
如果在didSet中給屬性設置新值,最終結果就是最后設置的這個值。

全局變量與局部變量

上面關于計算屬性和屬性觀察對全局變量和局部變量同樣成立。全局變量定義在任意的方法、函數、閉包或者類型定義之外。而局部變量則定義在方法、函數或閉包之內。

之前遇到的全局變量或者局部變量都跟存儲屬性類型,都是用來存儲值的。但實際上它們也能像計算屬性有計算變量。

提示
全局變量和常量與延時屬性類似,總是延時進行計算。但是它們并不需要使用@lazy標記。
局部常量和變量一定不是延時計算的。

類型屬性

實例屬性屬于某個特定類型的實例。每次創建的實例,它都擁有自己的一組獨立的屬性值,不受其它實例對象影響。

你還可以定義屬于類型本身的屬性。這些屬性是與具體的實例無關的,不管創建多少個實例都只有一份。這種屬性稱之為類型屬性

可以給值類型(結構體和枚舉類型)定義存儲和計算類型的類屬性,但是只能給類定義計算類型的類屬性。值類型的存儲屬性可以是變量或常量。

提示
一定要給存儲類型的類屬性設置初始值。

類型屬性語法

在C/Objective-C中只能使用全局靜態變量來定義依賴與某個屬性的變量或常量。但是在Swift中可以直接將它們定義為類型的一部分。其中結構體和枚舉類型中使用static關鍵字,而在類類型中則使用class關鍵字。

struct SomeStructure {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {        //return an Int value here
    }
}

enum SomeEnumeration {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {        //return an Int value here
    }
}

class SomeClass {
    class var computedTypeProperty: Int {        //return an Int value here
    }
}

提示
上面的計算屬性都是只讀的,但實際上可以定義為可讀可寫

使用類型屬性

類型屬性通過類型名字和點操作符進行訪問和設置,而不是通過實例對象:

println(SomeClass.computedTypeProperty)//print "42"println(SomeStructure.storedTypeProperty)//prints "Some value"SomeStructure.storedTypeProperty = "Another value."println(SomeStructure.storedTypeProperty)//prints "Another value."

下面演示了如何使用一個結構體來對聲道音量進行建模,其中每個聲道音量范圍為0-10。
Swift編程高級教程 變量與常量

struct AudioChannel {
    static let thresholdLevel = 10
    static var maxInputLevelForAllChannel = 0
    var currentLevel: Int = 0 {
        didSet {            if currentLevel > AudioChannel.thresholdLevel {
                currentLevel = AudioChannel.thresholdLevel
            }            if currentLevel > AudioChannel.maxInputLevelForAllChannels{
                AudioChannel.maxInputLevelForAllChannels = currentLevel
        }
    }
}var leftChannel = AudioChannel()var rightChannel = AudioChannel()

leftChannel.currentLevel = 7println(leftChannel.currentLevel)//prints "7"println(AudioChannel.maxInputLevelForAllChannels)//prints "7"

當修改其中一個聲道的值時,整個聲道的音量最大值就可能發生改變。而每個聲道都有自己的當前音量水平。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

板桥市| 株洲县| 乌鲁木齐县| 临朐县| 讷河市| 兴仁县| 沐川县| 吉水县| 龙口市| 天气| 略阳县| 九寨沟县| 福建省| 宁明县| 鄂伦春自治旗| 保亭| 神池县| 会泽县| 行唐县| 永昌县| 呼和浩特市| 兴文县| 师宗县| 西乡县| 左贡县| 宜君县| 陇南市| 甘泉县| 荥经县| 汝州市| 凤台县| 论坛| 陵川县| 大同市| 积石山| 罗定市| 南丹县| 肇州县| 特克斯县| 马山县| 隆尧县|