常量和變量是某個(gè)特定類型的值的名字,如果在程序運(yùn)行時(shí)值不能被修改的是一個(gè)常量,反之是一個(gè)變量。
創(chuàng)新互聯(lián)為企業(yè)提供:品牌網(wǎng)站制作、網(wǎng)絡(luò)營(yíng)銷策劃、小程序開發(fā)、營(yíng)銷型網(wǎng)站建設(shè)和網(wǎng)站運(yùn)營(yíng)托管,一站式網(wǎng)絡(luò)營(yíng)銷整體服務(wù)。實(shí)現(xiàn)不斷獲取潛在客戶之核心目標(biāo),建立了企業(yè)專屬的“全網(wǎng)整合營(yíng)銷推廣”,就用不著再為了獲取潛在客戶而苦惱,相反,客戶會(huì)主動(dòng)找您,生意就找上門來了!
Swift中的常量和變量在使用前必須先聲明。其中let
關(guān)鍵字聲明常量,var
關(guān)鍵字聲明變量:
//聲明一個(gè)名為maximumNumberOfLoginAttempts的整型常量,并且值為10let maximumNumberOfLoginAttempts = 10//聲明一個(gè)名為currentLoginAttempt的整型變量,并且值為0var currentLoginAttempt = 0
可以在同一行聲明多個(gè)變量,中間用逗號(hào),
隔開:
var x = 0.0, y = 0.0, z = 0.0
提示
如果在程序運(yùn)行的時(shí)候值不需要發(fā)生改變,應(yīng)該將它們聲明為常量,否則聲明為變量
變量的值可以進(jìn)行修改:
var friendlyWelcome = "Hello!"friendlyWelcome = "Bonjour!" //friendlyWelcome的值發(fā)生改變
常量的值一旦設(shè)置后就不能在修改:
let languageName = "Swift"languageName = "Swift++" //編譯時(shí)出錯(cuò)
在Swift中聲明常量或者變量可以在后面用冒號(hào):
指定它們的數(shù)據(jù)類型。
//聲明一個(gè)String類型的變量,可以存放String類型的值var welcomeMessage: String
提示
實(shí)際應(yīng)用中很少需要指定變量數(shù)據(jù)類型,Swift會(huì)根據(jù)所設(shè)置的值的類型進(jìn)行推導(dǎo)。
Swift中可以使用任意字符給常量和變量命名,包括Unicode編碼,比如中文、Emoji等:
let π = 3.14159let 你好 = "你好世界"let dog = "dogcow"
名字里面不能包含數(shù)學(xué)運(yùn)算符、箭頭、非法的Unicode字符以及不能識(shí)別的字符等,并且不能以數(shù)字開頭。同一個(gè)作用域的變量或者常量不能同名。
提示
如果想用關(guān)鍵字作為變量的名字,要用(`)包裹起來。為了方便理解,如果不是萬(wàn)不得已,不應(yīng)該使用關(guān)鍵字作為變量的名字。
println
函數(shù)可以打印常量或者變量的值:
println(friendlyWelcome) //打印出“Bonjour!”
println
是一個(gè)全局函數(shù),輸出時(shí)自動(dòng)在結(jié)尾添加換行。print
函數(shù)與它的功能類似,只是不會(huì)在結(jié)尾添加換行符。println
與NSLog
類似,可以用來輸出復(fù)雜的日志信息。Swift使用字符串插值來輸出變量和常量。
println("The current value of friendlyWelcome is \(friendlyWelcome)")//打印“The current value of friendlyWelcome is Bonjour!”
注釋是用來幫助理解和記憶代碼功能的,并不會(huì)參與編譯。Swift有兩種注釋形式,單行注釋和多行注釋:
//這是單行注釋,用兩個(gè)斜線開頭,直到改行的結(jié)尾/*這是多行注釋, 可以橫跨很多行, /*比C語(yǔ)言更加NB的是,*/它竟然還支持嵌套的注釋!*/
Swift中語(yǔ)句結(jié)尾的分號(hào);
不是必須的,不過如果想要在同一行中寫多個(gè)語(yǔ)句,則需要使用;
進(jìn)行分隔。
let cat = "cat"; println(cat)//打印“cat”
屬性是依賴于某個(gè)特定的類、結(jié)構(gòu)體或者枚舉類型的值。Swift有兩種屬性:存儲(chǔ)類型和計(jì)算類型。其中存儲(chǔ)類型可以作為實(shí)例的一部分存放變量或者常量的值,而計(jì)算類型的屬性值是通過運(yùn)算的來的。計(jì)算類型的屬性可以在類、結(jié)構(gòu)體和枚舉類型中出現(xiàn),但存儲(chǔ)類型只可能出現(xiàn)在類和結(jié)構(gòu)體類型中。
屬性一般依賴于一個(gè)特定類型的實(shí)例,但是也可以依賴于類本身。依賴于類型本身的屬性稱為類型屬性。
可以定義屬性觀察者來監(jiān)督屬性值的改變,從而作出響應(yīng)。
常量屬性let
的值在初始化后不能在改變,而變量屬性var
的值可以隨時(shí)更改。
struct FixedLengthRange { var firstValue: Int let length: Int }var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3) rangeOfThreeItems.firstValue = 6
如果一個(gè)結(jié)構(gòu)體實(shí)例被賦值給一個(gè)常量,則這個(gè)實(shí)例所擁有的存儲(chǔ)類型的屬性都不能在改變,包括變量屬性在內(nèi)。
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4) rangeOfFourItems.firstValue = 6//編譯錯(cuò)誤,firstValue的值不能改變
延時(shí)存儲(chǔ)屬性的初始值直到第一次使用的時(shí)候才進(jìn)行計(jì)算,在聲明時(shí)通過@lazy
進(jìn)行標(biāo)記。
提示
一定要將延時(shí)存儲(chǔ)屬性聲明為變量(var
),因?yàn)樗某跏贾悼赡軙?huì)在實(shí)例初始化完成后才有,而常量屬性一般在實(shí)例初始化完成之前就會(huì)有值。
當(dāng)屬性的初始值依賴于外部銀子,并且該因子的值在實(shí)例初始化完成之前不確定時(shí),延時(shí)屬性非常有用。如果屬性初始化時(shí)需要進(jìn)行大量的計(jì)算,也可以考慮使用延時(shí)屬性。
下面是延時(shí)屬性的示例:
class DataImporter { /* DataImporter是一個(gè)從外部文件導(dǎo)入數(shù)據(jù)的類。假設(shè)它需要花費(fèi)較多的時(shí)間進(jìn)行初始化 */ var fileName = "data.txt" //DataImporter類的數(shù)據(jù)導(dǎo)入功能} class DataManager { @lazy var importer = DataImporter() var data = String[]() //DataManager類提供數(shù)據(jù)管理功能} let manager = DataManager() manager.data += "Some data"manager.data += "Some more data"http://DataImporter實(shí)例還沒有創(chuàng)建
只有訪問DataManager
的importer
屬性時(shí)才會(huì)去創(chuàng)建這個(gè)對(duì)象。
println(manager.importer.filename)//創(chuàng)建importer屬性并打印“data.txt"
Objective-C類的對(duì)象可以使用屬性或者實(shí)例變量來存儲(chǔ)值。Swift中并沒有所謂的實(shí)例變量,而是將它們統(tǒng)一為屬性了,這樣使得屬性的聲明更加簡(jiǎn)化。
除了存儲(chǔ)屬性外,類、結(jié)構(gòu)體和枚舉類型還可以定義計(jì)算屬性。這些計(jì)算屬性并不能夠存儲(chǔ)值,而是通過getter
方法和可選的setter
方法來間接的獲取和設(shè)置其它屬性和值。
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)“
這個(gè)例子定義了三個(gè)結(jié)構(gòu)體來表示幾何形狀:
Point
封裝了(x, y)坐標(biāo)。
Size
封裝了寬度和高度。
Rect
用坐標(biāo)原點(diǎn)和大小定義一個(gè)矩形。
其中Rect
結(jié)構(gòu)體還提供了一個(gè)center
的計(jì)算屬性。這個(gè)屬性的值是由矩形的origin
和size
屬性決定的,它本身并不需要存儲(chǔ)信息。但是改變center
的值,會(huì)間接的修改矩形的其它屬性。
setter
的聲明如果沒有為計(jì)算屬性的setter
的新值指定名字,則默認(rèn)使用newValue
。下面是Rect
結(jié)構(gòu)體的另外一種寫法:
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) } } }
如果一個(gè)計(jì)算屬性只有getter
而沒有聲明setter
,則它是一個(gè)只讀的計(jì)算屬性。只讀屬性只能通過點(diǎn)語(yǔ)法返回一個(gè)值,而不能對(duì)它進(jìn)行設(shè)置。
提示
必須使用var
聲明計(jì)算屬性,包括只讀的計(jì)算屬性在內(nèi),因?yàn)樗鼈兊闹凳强赡芨淖兊?。?code>let只能用于常量的聲明,表示它們的值不能發(fā)生改變。
還可以省略只讀計(jì)算屬性聲明中的get
關(guān)鍵字。
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”
屬性觀察者用來觀察和響應(yīng)屬性值的變化。每次設(shè)置屬性的值都會(huì)調(diào)用相應(yīng)的觀察者,哪怕是設(shè)置相同的值。
可以給除延時(shí)存儲(chǔ)屬性以外的任何存儲(chǔ)屬性添加觀察者。通過重寫屬性,可以在子類中給父類的屬性(包括存儲(chǔ)屬性和計(jì)算屬性)添加觀察者。
提示
不需要給類本身定義的計(jì)算屬性添加觀察者,完全可以在計(jì)算屬性的setter
中完成對(duì)值的觀察。
通過下面兩個(gè)方法對(duì)屬性進(jìn)行觀察:
willSet
在屬性的值發(fā)生改變之前調(diào)用。
didSet
在設(shè)置完屬性的值后調(diào)用。
如果沒有給willSet
指定參數(shù)的話,編譯器默認(rèn)提供一個(gè)newValue
做為參數(shù)。同樣,在didSet
中如果沒有提供參數(shù)的話,默認(rèn)為oldValue
。
提示
willSet
和didSet
觀察者在屬性進(jìn)行初始化的時(shí)候不會(huì)被調(diào)用。
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
中給屬性設(shè)置新值,最終結(jié)果就是最后設(shè)置的這個(gè)值。
上面關(guān)于計(jì)算屬性和屬性觀察對(duì)全局變量和局部變量同樣成立。全局變量定義在任意的方法、函數(shù)、閉包或者類型定義之外。而局部變量則定義在方法、函數(shù)或閉包之內(nèi)。
之前遇到的全局變量或者局部變量都跟存儲(chǔ)屬性類型,都是用來存儲(chǔ)值的。但實(shí)際上它們也能像計(jì)算屬性有計(jì)算變量。
提示
全局變量和常量與延時(shí)屬性類似,總是延時(shí)進(jìn)行計(jì)算。但是它們并不需要使用@lazy
標(biāo)記。
局部常量和變量一定不是延時(shí)計(jì)算的。
實(shí)例屬性屬于某個(gè)特定類型的實(shí)例。每次創(chuàng)建的實(shí)例,它都擁有自己的一組獨(dú)立的屬性值,不受其它實(shí)例對(duì)象影響。
你還可以定義屬于類型本身的屬性。這些屬性是與具體的實(shí)例無(wú)關(guān)的,不管創(chuàng)建多少個(gè)實(shí)例都只有一份。這種屬性稱之為類型屬性。
可以給值類型(結(jié)構(gòu)體和枚舉類型)定義存儲(chǔ)和計(jì)算類型的類屬性,但是只能給類定義計(jì)算類型的類屬性。值類型的存儲(chǔ)屬性可以是變量或常量。
提示
一定要給存儲(chǔ)類型的類屬性設(shè)置初始值。
在C/Objective-C中只能使用全局靜態(tài)變量來定義依賴與某個(gè)屬性的變量或常量。但是在Swift中可以直接將它們定義為類型的一部分。其中結(jié)構(gòu)體和枚舉類型中使用static
關(guān)鍵字,而在類類型中則使用class
關(guān)鍵字。
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 } }
提示
上面的計(jì)算屬性都是只讀的,但實(shí)際上可以定義為可讀可寫
類型屬性通過類型名字和點(diǎn)操作符進(jìn)行訪問和設(shè)置,而不是通過實(shí)例對(duì)象:
println(SomeClass.computedTypeProperty)//print "42"println(SomeStructure.storedTypeProperty)//prints "Some value"SomeStructure.storedTypeProperty = "Another value."println(SomeStructure.storedTypeProperty)//prints "Another value."
下面演示了如何使用一個(gè)結(jié)構(gòu)體來對(duì)聲道音量進(jìn)行建模,其中每個(gè)聲道音量范圍為0-10。
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"
當(dāng)修改其中一個(gè)聲道的值時(shí),整個(gè)聲道的音量最大值就可能發(fā)生改變。而每個(gè)聲道都有自己的當(dāng)前音量水平。
當(dāng)前名稱:Swift編程高級(jí)教程變量與常量
轉(zhuǎn)載來于:http://jinyejixie.com/article18/jdoigp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、Google、軟件開發(fā)、面包屑導(dǎo)航、微信公眾號(hào)、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)