Swift基礎資料類型,swift資料類型

來源:互聯網
上載者:User

Swift基礎資料類型,swift資料類型
常量和變數

常量和變數由一個特定名稱來表示,如maximumNumberOfLoginAttempt 或者 welcomeMessage。常量所指向的是一個特定類型的值,如數字10或者字元”hello”。變數的值可以根據需要不斷修改,而常量的值是不能夠被二次修改的。

常量和變數的聲明

常量和變數在使用前都需要聲明,在Swift中使用let關鍵詞來聲明一個常量,var關鍵詞聲明一個變數。如下面例子

let maximumNumberOfLoginAttempts = 10var currentLoginAttempt = 0

以上代碼可以理解為:

聲明一個叫maximumNumberOfLoginAttempts的值為10的常量。然後聲明一個變數currentLoginAttempt初始值為0。

在這個例子中,最大的登入嘗試次數10是不變的,因此聲明為常量。而已經登入的嘗試次數是可變的,因此定義為變數。也可以在一行中聲明多個變數或常量,用,號分隔:

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

註:如果一個值在之後的代碼中不會再變化,應該用let關鍵詞將它聲明為常量。變數只用來儲存會更改的值。

 類型註解

在聲明常量和變數時,可以使用註解來註明該變數或常量的類型。使用:號加空格加類型名在變數或常量名之後就可以完成類型註解。下面的例子就是聲明了一個變數叫welcomeMessage,註解類型為字串String:

var welcomeMessage: String

分號 “:” 在這的作用就像是在說:…是…類型的,因此上述代碼可以理解為:

聲明一個叫welcomeMessage的變數,它的類型是String

這個類型註解表明welcomeMessage變數能無誤地儲存任何字串類型的值,比如welcomeMessage = “hello”

註:實際編程中很少需要使用類型註解,定義常量或者變數的時候Swift已經根據初始化的值確定了類型資訊。Swift幾乎都可以隱式的確定變數或常量的類型。

 分號

和其它一些程式設計語言不同,Swift不需要使用分號 ; 來分隔每一個語句。當然你也可以選擇使用分號,或者你想在一行中書寫多個語句。

let cat = ""; println(cat)// prints ""
 整數

整數就是像42和-23這樣不帶分數的數字,包括有符號(正數,負數,0)和無符號(正數,0)。Swift提供了8、16、32和64位的數字形式,和C語言類似,可以使用8位的不帶正負號的整數UInt8,或者32位的整數Int32.像其他Swift類型一樣,這些類型名的首字母大寫

整數邊界

使用min或max值來擷取該類型的最大最小值,如

let minValue = UInt8.min // minValue is equal to 0, and is of type UInt8let maxValue = UInt8.max // maxValue is equal to 255, and is of type UInt8

這些值邊界值區分了整數的類型(比如UInt8),所以可以像該類型的其他值一樣被用在運算式中而不用考慮益處的問題。

Int類型

一般來說,編程人員在寫代碼時不需要選擇整數的位元,Swift提供了一種額外的整數類型Int,是和當前機器環境的字長相同的整數位元

  • 在32位機器上,Int和Int32一樣大小
  • 在64位機器上,Int和Int64一樣大小

除非你確實需要使用特定字長的正數,盡量使用Int類型。這保證了代碼的可移植性。即使在32位的平台上,Int也可以儲存-2,147,483,648 到2,147,483,647範圍內的值,這對大部分正數來講已經足夠了。

 

5、浮點數

浮點數就是像3.14159,0.1,-273.15這樣帶分數的數字。浮點數可以表達比Int範圍更廣(更大或更小)的數值。swift支援兩種帶符號浮點數類型:

  • Double類型能表示64位的有符號浮點數。當需要表的數字非常大或者精度要求非常高的時候可以使用Double類型。
  • Float類型能表示32為的有符號浮點數。當需要表達的數字不需要64位精度的時候可以使用Float類型。

    注 Double 至少有15位小數,Float至少有6位小數。合適的浮點數小數位元取決於你代碼裡需要處理的浮點數範圍。

6、型別安全和類型推導

Swift是一種型別安全的語言。型別安全就是說在編程的時候需要弄清楚變數的類型。如果您的代碼部分需要一個字串,你不能錯誤地傳遞一個整數類型。

因為Swift是型別安全的,它會在編譯的時候就檢查你的代碼,任何類型不符時都會報錯。這使得編程人員能夠儘快捕獲並儘可能早地在開發過程中修正錯誤。

類型檢查可以在使用不同類型的值時協助避免錯誤。但是,這並不意味著你必須指定每一個常量和變數所聲明的類型。如果不指定你需要的類型,Swift使用類型推導來指定出相應的類型。類型推導使編譯器在編譯的時候通過你提供的初始化值自動推匯出特定的運算式的類型。

類型推導使Swift比起C或Objective-C只需要更少的型別宣告語句。常量和變數仍然顯式類型,但大部分指定其類型的工作Swift已經為你完成了。

當你聲明一個常量或變數並給出初始實值型別的時候,類型推導就顯得特別有用。這通常是通過給所聲明的常量或變數賦常值來完成的。 (常值是直接出現在原始碼中的值,如下面的例子42和3.14159 。 )

例如,如果您指定42到一個新的常數變數,而不用說它是什麼類型,Swift推斷出你想要的常量是一個整數,因為你已經初始化它為一個整數

let meaningOfLife= 42// meaningOfLife is inferred to be of typeInt

同樣,如果你不指定浮點值的類型,Swift推斷出你想要建立一個Double:

let pi = 3.14159// pi is inferred to be of type Double

Swift總是選擇Double(而非Float)當它需要浮點數類型時。如果你在一個運算式中把整數和浮點數相加,會推導一個Double類型:

let anotherPi= 3 + 0.14159// anotherPi is also inferred to be of typeDouble

常值3沒有顯示指明類型,所以Swift根據運算式中的浮點值推出輸出類型Double。

 

數值量表達

整型常量可以寫成:

  • 一個十進位數,不帶首碼
  • 一個位元,用首碼0b
  • 一個八位元,用0o首碼
  • 一個十六進位數,以0x首碼

所有如下用這些整型常量都可以來表達十進位值的17

let decimalInteger= 17let binaryInteger = 0b10001 // 17 in binary notationlet octalInteger = 0o21 // 17 in octal notationlet hexadecimalInteger = 0x11 // 17 inhexadecimal notation

浮點可以是十進位(不帶首碼)或十六進位(以0x首碼),小數點的兩側必須始終有一個十進位數(或十六進位數)。他們也可以有一個可選的指數,由一個大寫或小寫e表示十進位浮點數表示,或大寫/小寫p表示十六進位浮點數

帶指數exp的十進位數,實際值等於基數乘以10的exp次方,如:

  • 1.25e2表示1.25×102,或者125.0.
  • 1.25e-2表示1.25×10-2,或者0.0125.

帶指數exp的十六進位數,實際值等於基部數乘以2的exp次方,如:

  • 0xFp2表示15×22,或者60.0.
  • 0xFp-2表示15×2-2,或者3.75.

所有如下這些浮點常量都表示十進位的12.1875:

let decimalDouble= 12.1875let exponentDouble= 1.21875e1let hexadecimalDouble= 0xC.3p0

數字值可以包含額外的格式,使它們更容易閱讀。整數和浮點數都可以被額外的零填充,並且可以包含底線,以增加可讀性。以上格式都不影響變數的值:

let paddedDouble= 000123.456let oneMillion= 1_000_000let justOverOneMillion= 1_000_000.000_000_1
數實值型別轉換

為代碼中所有通用的數值型整型常量和變數使用Int類型,即使它們已知是非負的。這意味著代碼中的數值常量和變數能夠相互相容並且能夠與自動推匯出的類型相互匹配。

只有因為某些原因(效能,記憶體佔用或者其他必須的最佳化)確實需要使用其他數實值型別的時候,才應該使用這些數實值型別。這些情況下使用顯式指定長度的類型有助於發現值範圍溢出,同時應該留下文檔。

 整數轉換

可以儲存在一個整數常量或變數的範圍根據每個數實值型別是不同的。一個Int8常量或變數可以儲存範圍-128到127之間的數,而一個UInt8常量或變數可以儲存0到255之間的數字。錯誤的賦值會讓編譯器報錯:

let cannotBeNegative: UInt8 = -1// UInt8 cannot store negative numbers, and so this will report an errorlet tooBig: Int8 = Int8.max + 1// Int8 cannot store a number larger thanits maximum value,// and so this will also report an error

因為每個數字類型可以儲存不同範圍的值,你必須在基礎數實值型別上逐步做轉換。這種可以防止隱藏的轉換錯誤,並協助明確你的代碼中類型轉換的意圖。

要轉換一個特定的數字類型到另一個,你需要定義一個所需類型的新變數,並用當前值初始化它。在下面的例子中,常量twoThousand是UInt16類型的,而常量one是UINT8類型的。它們不能被直接相加的,因為類型不同。相反的,該樣本調用UInt16(one)來建立一個用變數one的值初始化的UInt16類型的新變數,並且使用這個值來代替原來的值參與運算:

let twoThousand: UInt16 = 2_000let one: UInt8 = 1let twoThousandAndOne= twoThousand + UInt16(one)

可以由於相加雙方的類型都是UInt16的,現在可以做加法運算了。輸出常量(twoThousandAndOne)被推斷為UInt16類型的,因為它是兩個UInt16的值的總和。

SomeType(ofInitialValue)是Swift預設的類型轉換方式。實現上看,UInt16的有一個接受UINT8值的構造器,這個構造器用於從現有UInt8構造出一個新的UInt16的變數。你不能傳入任意類型的參數,它必須是一個類型的UInt16初始化能接受的類型。如何擴充現有類型,規定接受新的類型(包括你自己的類型定義)可以參見 Extensions。

整數和浮點數轉換

整數和浮點類型之間的轉化必須顯式聲明

let three = 3let pointOneFourOneFiveNine= 0.14159let pi = Double(three) +pointOneFourOneFiveNine// pi equals 3.14159, and is inferred to beof typde Double

這裡,常量three的值被用來建立Double類型的新變數,從而使運算式兩側是相同的類型。如果沒有這個轉換,加法操作不會被允許。反之亦然,一個整數類型可以用double或float值進行初始化:

let integerPi= Int(pi)// integerPi equals 3, and is inferred tobe of type Int

當使用這種方式初始化一個新的整數值的時候,浮點值總是被截斷。這意味著,4.75變為4,和-3.9變為-3。

註:數實值型別常量/變數的類型轉換規則和數字類型常值的轉換規則不同。常值3可以直接與常值0.14159相加,因為常值沒有一個明確的類型。他們的類型是被編譯器推匯出來的。

類型別名

類型別名為現有類型定義的可替代名稱。你可以使用typealias關鍵字定義類型別名。類型別名可以協助你使用更符合上下文語境的名字來指代一個已存在的類型,比如處理一個外來的有指定長度的類型的時候:

typealias AudioSample = UInt16

一旦你定義了一個類型別名,你可以在任何可能使用原來的名稱地方使用別名:

var maxAmplitudeFound= AudioSample.min// maxAmplitudeFound is now 0

這裡,AudioSample被定義為一個UInt16的別名。因為它是一個別名,調用AudioSample.min實際上是調用UInt16.min,從而給maxAmplitudeFound變數賦初始值0。

布爾類型

Swift中的布爾類型使用Bool定義,也被稱為Logical(邏輯)類型,可選值是true和false:

let orangesAreOrange = truelet turnipsAreDelicious = false

這裡 orangesAreOrange和turnipsAreDelicious的類型被推導為Bool 因為他們被初始化被Bool類型的常值。跟Int和Double類型一樣,在定義布爾類型的時候不需要顯式的給出資料類型,只需要直接賦值為true或false即可 。當使用確定類型的常值初始化一個常量/變數的時候,類型推導使Swift代碼更精確和可讀。 布爾類型在條件陳述式中特別適用,比如在if語句中

if turnipsAreDelicious {println("Mmm, tasty turnips!")} else {println("Eww, turnips are horrible.")}// prints "Eww, turnips are horrible."

像if語句這樣的條件陳述式,我們會在之後的章節ControlFlow有詳細介紹。 Swift的型別安全策略會防止其他非布爾類型轉換為布爾類型使用,比如

let i = 1if i {// this example will not compile, and will report an error}

就會報錯,但這在其他程式設計語言中是可行的。但是如下的定義是正確的:

let i = 1if i == 1 {// this example will compile successfully}

i == 1的結果就是一個布爾類型,所以可以通過類型檢查。像i==1這種比較將會在章節[Basic Operators]中討論。上面的例子也是一個Swift型別安全的例子。型別安全避免了偶然的類型錯誤,保證了代碼的意圖是明確的。

元群組類型

元群組類型可以將一些不同的資料類型組裝成一個元素,這些資料類型可以是任意類型,並且不需要是同樣的類型。

在下面的例子中,(404, “Not Found”) 是一個HTTP狀態代碼。HTTP狀態代碼是請求網頁的時候返回的一種特定的狀態編碼。404錯誤的具體含義是頁面未找到。

let http404Error = (404, “Not Found”) // http404Error is of type (Int, String), and equals (404, “NotFound”)

這個元組由一個Int和一個字串String組成,這樣的組合即包含了數字,也包含了便於人們認知的字串描述。這個元組可以描述為類型(Int,String)的元組。

編程人員可以隨意地建立自己需要的元群組類型,比如 (Int, Int, Int), 或者(String, Bool)等。同時組成元組的類型數量也是不限的。 可以通過如下方式分別訪問一個元組的值:

let (statusCode, statusMessage) = http404Errorprint("The status code is \(statusCode)")// prints "The status code is 404"print("The status message is \(statusMessage)")// prints "The status message is Not Found"

另外,也可以使用元素序號來選擇元組中的值,注意序號是從0開始的

print("The status code is \(http404Error.0)")// prints "The status code is 404"print("The status message is \(http404Error.1)")// prints "The status message is Not Found"

在建立一個元組的時候,也可以直接指定每個元素的名稱,然後直接使用元組名.元素名訪問,如:

let http200Status = (statusCode: 200, description: "OK")print("The status code is \(http200Status.statusCode)")// prints "The status code is 200"print("The status message is \(http200Status.description)")// prints "The status message is OK"

元群組類型在作為函數傳回值的時候特別適用,可以為函數返回更多的使用者需要的資訊。比如一個請求web頁面的函數可以返回(Int,String)類型的元組來表徵頁面擷取的成功或者失敗。返回兩個不同類型組成的元組可以比只返回一個類型的一個值提供更多的返回資訊。詳見Functions with Multiple Return Values

可選類型

在一個值可能不存在的時候,可以使用可選類型。這種類型的定義是:要麼存在這個值,且等於x,要麼在這個值 不存在。

註:這種類型在C和Objective-C中是不存在的,但是Objective-C中有一個相似的類型,叫nil,但是僅僅對對象有用。對其他的情況,Object-C方法返回一個特殊值(比如NSNotFound)來表明這個值不存在。這種方式假設方法調用者知道這個特殊值的存在和含義。Swift的可選類型協助你定義任意的值不存在的情況。

下面給出一個例子,在Swift中String類型有一個叫toInt的方法,能夠將一個字串轉換為一個Int類型。但是需要注意的是,不是所有的字串都可以轉換為整數。比如字串”123″可以轉換為123,但是”hello, world”就不能被轉換。

let possibleNumber = "123"let convertedNumber = possibleNumber.toInt()// convertedNumber is inferred to be of type "Int?", or "optional Int"

由於toInt方法可能會失敗,因此它會返回一個可選的Int類型,而不同於Int類型。一個可選的Int類型被記為Int?,不是Int。問號表明它的值是可選的,可能返回的是一個Int,或者返回的值不存在。

if語句和強制解包

編程人員可以使用if語句來檢測一個可選類型是否包含一個特定的值,如果一個可選類型確實包含一個值,在if語句中它將返回true,否則返回false。如果你已經檢測確認該值存在,那麼可以使用或者輸出它,在輸出的時候只需要在名稱後面加上驚嘆號(!)即可,意思是告訴編譯器:我已經檢測好這個值了,可以使用它了。如:

if convertedNumber {print("\(possibleNumber) has an integer value of \(convertedNumber!)")} else {print("\(possibleNumber) could not be converted to an integer")}// prints "123 has an integer value of 123"

像if語句這樣的條件陳述式,我們會在之後的章節ControlFlow有詳細介紹。

選擇綁定

選擇綁定協助確定一個可選值是不是包含了一個值,如果包含,把該值轉化成一個臨時常量或者變數。選擇綁定可以用在if或while語句中,用來在可選類型外部檢查是否有值並提取可能的值。if和while語句詳見ControlFlow。

方法如下:

if let constantName = someOptional {statements}

那麼上一個例子也可以改寫為:

var myString:String?myString = "Hello, Swift!"if let yourString = myString {    print("Your string has - \(yourString)")}else{    print("Your string does not have a value")}

 

隱式解包可選類型

在上面的例子中,可選類型表示一個常量/變數可以沒有值。可選類型可以被if語句檢測是否有值,並且可以被可選綁定解包。

但是在一些情況下,可選類型是一直有效,那麼可以通過定義來隱式地去掉類型檢查,強制使用可選類型。這些可選類型被成為隱式解包的可選類型。你可以直接在類型後面加! 而不是?來指定。

隱式解包的可選類型主要用在一個變數/常量在定義瞬間完成之後值一定會存在的情況。這主要用在類的初始化過程中,詳見Unowned References and Implicitly Unwrapped Optional Properties.

隱式解包的可選類型本質是可選類型,但是可以被當成一般類型來使用,不需要每次驗證值是否存在。如下的例子展示了可選類型和解包可選類型之間的區別。

 

let possibleString: String? = "An optional string."print(possibleString!) // requires an exclamation mark to access its value// prints "An optional string."let assumedString: String! = "An implicitly unwrapped optional string."print(assumedString) // no exclamation mark is needed to access its value// prints "An implicitly unwrapped optional string."

你可以把隱式解包可選類型當成對每次使用的時候自動解包的可選類型。即不是每次使用的時候在變數/常量後面加!而是直接在定義的時候加。

註:如果一個隱式解包的可選類型不包含一個實際值,那麼對它的訪問會拋出一個執行階段錯誤。在變數/常量名後面加!的情況也是一樣的。

你依然可以把解包可選類型當成正常的可選類型來探測是否有值。

if assumedString {print(assumedString)}// prints "An implicitly unwrapped optional string."

或者通過選擇綁定檢查

if let definiteString = assumedString {print(definiteString)}// prints "An implicitly unwrapped optional string."

註:如果一個可選類型存在沒有值的可能的話,不應該使用解包可選類型。這種情況下,一定要使用正常的可選類型。

斷言

可選類型讓編程人員可以在運行期檢測一個值是否存在,然後使用代碼來處理不存在的情況。但是有些情況下,如果一個值 不存在或者值不滿足條件會直接影響代碼的執行,這個時候就需要使用斷言。這種情況下,斷言結束程式的執行從而提供調試的依據。

使用斷言調試

斷言是一種即時檢測條件是否為true的方法,也就是說,斷言假定條件為true。斷言保證了後續代碼的執行依賴於條件的成立。如果條件滿足,那麼代碼繼續執行,如果這個條件為false,那麼代碼將會中斷執行。

在Xcode中,在調試的時候如果中斷,可以通過查看調試語句來查看宣告失敗時的程式狀態。斷言也能提供適合的debug資訊。 使用全域函數assert來使用斷言調試,assert函數接受一個布林運算式和一個宣告失敗時顯示的訊息,如:

let age = -3assert(age >= 0, "A person's age cannot be less than zero")// this causes the assertion to trigger, because age is not >= 0

當前一個條件返回false的時候,後面的錯誤記錄檔將會輸出。

在這個例子中,只有當age >= 0的時候,條件被判定為true,但是age = -3,所以條件判定為false,輸出錯誤記錄檔 “A person’s age cannot be less than zero”。

當然錯誤記錄檔也可以省略,但是這樣不利於調試,如

assert(age >= 0)
使用斷言的時機

當需要檢測一個條件可能是false,但是代碼運行必須返回true的時候使用。下面給出了一些常用情境,可能會用到斷言檢測:

  • 傳遞一個整數類型下標的時候,比如作為數組的Index,這個值可能太小或者太大,從而造成數組越界;
  • 傳遞給函數的參數,但是一個無效的參數將不能在該函數中執行
  • 一個可選類型現在是nil,但是在接下來的代碼中,需要是非nil的值才能夠繼續運行。

詳見 Subscripts和Functions

註:斷言會導致程式啟動並執行中止,所以如果異常是預期可能發生的,那麼斷言是不合適的。這種情況下,異常是更合適的。斷言保證錯誤在開發過程中會被發現,發布的應用裡最好不要使用。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.