級別: ★☆☆☆☆
標籤:「iOS」「Swift 5.1」「常量變量」「元組」「可選項」「可選綁定」
做者: 沐靈洛
審校: QiShare團隊php
常量和變量:常量的值一旦設置就不能更改,而變量能夠在未來設置爲不一樣的值。常量和變量必須在使用以前聲明。常量聲明使用let
關鍵字。變量聲明使用var
關鍵字。git
let num1 = 10 //!< 聲明一個常量num1,而且賦初始值10
var num2 = 5 //!< 聲明一個變量num2,而且賦初始值5
let a = 1, b = 3, c = 4 //!< 同時聲明多個常量並賦初值
var aa = 1, bb = 3, cc = 4 //!< 同時聲明多個變量並賦初值
複製代碼
類型註釋:聲明常量或變量時,能夠提供類型註釋,以清楚常量或變量能夠存儲的值的類型。經過在常量或變量名稱後面放置冒號,後跟空格,後跟要使用的類型的名稱來編寫類型註釋。github
let num3 : Int = 3 //!<聲明一個常量num1,能夠存儲的值得類型是Int類型,而且賦初始值3
var str : String = "QS" //!< 聲明一個變量str,能夠存儲的值得類型是String類型,而且賦初始值"QS"
let a : Int = 1, b : [Int] = [3,4,5], c : String = "constant" //!< < 同時聲明,多個能夠存儲不一樣類型值的常量,並賦相應類型初值
var aa : Int = 1, bb : [Int] = [3,4,5], cc : String = "change" //!< < 同時聲明,多個能夠存儲不一樣類型值的變量,並賦相應類型初值
複製代碼
命名規則:常量和變量名稱幾乎能夠包含任何字符,包括Unicode字符。可是常量和變量名稱不能包含空格字符,數學符號,箭頭,專用Unicode標量值或行和框繪製字符。也不能以數字開頭,但能夠包含在名稱的其餘地方。使用Swift關鍵字做爲變量名稱時,須要使用``包裹。以下例所示:算法
let π = 3.14159
let 你好 = "你好世界"
let 🐶🐮 = "dogcow"
let s2r = "s2r"
let `default` = "default"//!< 使用Swift關鍵字做爲變量名稱時,須要使用``包裹
複製代碼
一旦聲明瞭某個類型的常量或變量,就不能再使用相同的名稱聲明它,或者將其更改成存儲不一樣類型的值。也不能將常量變爲變量或變量變爲常量。
打印方法:
print(_:separator:terminator:)
它能夠將一個或多個值輸出到控制檯。separator和terminator參數都有默認值分別是" "
和\n
,使用時能夠忽略。編程
let word = "張翼德"
print(word)//!< 控制檯輸出:張翼德
let p1 = "HOW"
let p2 = "ARE"
let p3 = "YOU?"
print(p1,p2,p3,separator: "...")//!< 控制檯輸出:HOW...ARE...YOU?
print(p1,p2,p3,separator: ".",terminator: "FINE THANKS\n")//!<控制檯輸出:HOW.ARE.YOU?FINE THANKS
複製代碼
print(_ separator:terminator:to:)
它能夠將一個或多個值輸出到合適的輸出。separator和terminator參數都有默認值分別是" "
和\n
,使用時能夠忽略。swift
let p1 = "HOW"
let p2 = "ARE"
let p3 = "YOU?"
var outputStream = ""
print(p1,p2,p3,separator: ".",terminator: "FINE THANKS\n",to:&outputStream)
print("打印的數據,寫入了outputStream變量中最終輸出爲:\(outputStream)")//!< 控制檯輸出:打印的數據,寫入了outputStream變量中最終輸出爲:HOW.ARE.YOU?FINE THANKS
複製代碼
Swift使用字符串插值將常量或變量的名稱包含在較長字符串中做爲佔位符,並提示Swift將其替換爲該常量或變量的當前值。將名稱括在括號中,並在左括號前用反斜槓轉義它:安全
let word = "張翼德"
print("我乃燕人\(word)也!誰敢與我決一雌雄?")
複製代碼
代碼註釋:單行註釋以兩個正斜槓開頭//
。多行註釋以正斜槓開頭後跟星號/*
,以星號後跟正斜槓*/
結束。Swift中的多行註釋能夠嵌套在其餘多行註釋中。bash
/* This is the start of the first multiline comment.
/* This is the second, nested multiline comment. */
This is the end of the first multiline comment. */
複製代碼
分號:Swift不要求代碼中的每一個語句以後都須要加分號;
咱們能夠寫也能夠不寫。若是一行代碼中有多個語句,則必需要加分號;
服務器
**整型:**沒有小數部分,整數有符號(正,零或負)或無符號(正或零)。Swift提供8,16,32和64位格式的有符號和無符號整數。這些整數遵循相似於C的命名約定,由於8位無符號整數屬於類型UInt8,32位有符號整數屬於類型Int32。微信
整數邊界:
//無符號
let unsignedMinValue = UInt8.min // UInt8類型最小值 0
let unsignedMaxValue = UInt8.max // UInt8類型最大值 255
//有符號
let minValue = Int8.min // Int8類型最小值 -128
let maxValue = Int8.max // Int8類型最大值 127
複製代碼
let cannotBeNegative: UInt8 = -1 //報錯代碼:無符號的8位整數類型不能表示有符號的-1
let tooBig: Int8 = Int8.max + 1 //報錯代碼:Int8表示範圍0-255 不能表示256報錯
複製代碼
let twoThousand: UInt16 = 2000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)
複製代碼
浮點數字: 浮點數是具備小數部分的數字,浮點類型能夠表示比整數類型更寬範圍的值。例如3.14159,0.1,和-273.15。Swift提供了兩種帶符號的浮點數類型:Double 表示64位浮點數。 Float 表示32位浮點數。 整數與浮點數之間的轉換: 整數轉浮點數
let three = 3 //須要類型轉換,使用常量three建立一個double類型的新值:Double(three),不然這種相加操做不被容許會報錯
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
複製代碼
浮點數轉整數
let pi = 3.14159
let integerPi = Int(pi)//採用這種形式則浮點數老是被截斷,這意味着4.76->4 ,3.9->3
複製代碼
類型安全和類型判斷:
Swift是一種類型安全的語言,編譯代碼時執行類型檢查,並將任何不匹配的類型標記爲錯誤,讓咱們在開發過程當中儘早捕獲並修復錯誤。好比:定義的變量或常量是String
類型的,那麼咱們就不能使用Int
類型賦值。因此Swift鼓勵咱們在使用變量或常量時,可以清楚的知道所需的值的類型。但並不意味着咱們必須指定聲明的變量或常量的類型。若是未指定所需的值類型,Swift將使用類型推斷來匹配適當的類型。類型推斷使編譯器可以在編譯代碼時自動推斷出特定表達式的類型,只需檢查咱們提供的值便可。類型推斷有助於使Swift代碼在使用其類型已知的其餘值初始化常量或變量時簡潔性和可讀性更高。
使用初始值聲明常量或變量時,類型推斷特別有用。推斷浮點數的類型時,Swift老是選擇Double
(而不是Float
)。如let π = 3.14159
,π 將會推斷爲Double
類型。let π = 3 + 0.14159
,Double
類型做爲加法的一部分,因此也會推斷爲Double
類型 數值(浮點,整數)類型表達式:
一個十進制數(decimal),無前綴 一個二進制數(binary),有0b前綴 一個八進制數(octal),有0o前綴 一個十六進制數(hexadecimal),有0x前綴
一個整數17,使用不一樣進制數進行表示
let decimalInteger = 17
let binaryInteger = 0b10001 // 二進制數表示17
let octalInteger = 0o21 // 八進制數表示17
let hexadecimalInteger = 0x11 // 16進制數表示17
複製代碼
浮點數能夠是沒有前綴的十進制數,或者帶有0x
前綴的十六進制數,無論是無前綴的十進制數仍是有前綴的十六進制數它們必須始終在小數點的兩邊都有一個數字。(基於此咱們可能會用到表達式去實現)十進制數有一個可選的指數,可使用大寫或小寫的e來表示,即:en = 10ⁿ
,十六進制數也必須會有一個可選的指數,可使用大寫或小寫的p來表示,即:pn = 2ⁿ
.
浮點數十進制數表示:
1.25e2表示1.25 * 10^2,或125.0。 1.25e-2表示1.25 * 10^ -2,或0.0125。
浮點數十六進制數表示:
0xFp2指15 * 2^2,或60.0。
0xFp-2表示15 * 2^-2,或3.75。
一個浮點數12.1875,可使用以下表達式:
let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0
複製代碼
數字文字能夠包含額外的格式以使其更易於閱讀。整數和浮點數均可以用額外的零填充,而且能夠包含下劃線以幫助提升可讀性。這兩種格式都不會影響文字的基礎值:
let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1
複製代碼
**定義別名:**使用關鍵字:typealias
爲現有類型定義別名。
typealias MyString = String
var my :MyString?
my = "我"
print(my!)
複製代碼
布爾:Swift有一個基本的布爾類型,叫作Bool
。Swift只提供了兩個布爾常量值:true
和false
。
元組: 元組中的值能夠是任何類型,而且沒必要彼此具備相同的類型。咱們能夠建立任意數量,任何類型,任意順序的組合,做爲一個元組。元組做爲函數的返回值特別有用。
let someGrop = ("元組",401,"未受權",[1,3],true,["name" : "張三"])
print(someGrop)
複製代碼
分解元組中的常量或者變量單獨去使用。
let httpError = (401,"未受權")//!< httpError能夠被描述爲(Int,String)類型的元組
let (code,error) = httpError
print(code,error)//code:401 error 未受權
複製代碼
元組中包含許多項不一樣類型的常量或者變量,咱們須要有針對性的分解出某一個元素。
let someGrop = ("元組",401,"未受權",[1,3],true,["name" : "張三"])
let (name,_,_,_,_,_) = someGrop
print(name)
複製代碼
使用從零開始的索引訪問元組中的各個元素值
let someGrop = ("元組",401,"未受權",[1,3],true,["name" : "張三"])
let name = someGrop.0
let num = someGrop.1
let des = someGrop.2
let array = someGrop.3
print(name,num,des,array)
複製代碼
定義元組時能夠命名元組中各個元素。
let httpError = (code:401,error:"未受權")
//元素單獨使用
print(httpError.code,httpError.error)
複製代碼
定義元組時不賦初值
let httpSubError : (Int,String)?
httpSubError = (401,"未受權")
print(httpSubError!)
//也能夠
let httpSubError : (code:Int,error:String)?
httpSubError = (401,"未受權")
print(httpSubError!.code)
複製代碼
可選項(Optionals):
當某個類型變量的值可能爲空的場景,咱們須要使用Optionals(可選項)。一個可選表明兩種可能:有值而且你能夠解開可選項(optional)的包獲取到這個值,不然沒有值。
選項的概念在C或Objective-C中不存在。Objective-C中最接近的是一個具有返回值的方法在缺乏有效對象的狀況下能夠返回nil,不然返回此對象。可是這種場景只適用於對象 ,而對於結構體,基本C類型或枚舉值這些類型,Objective-C的方法是返回特殊值(例如NSNotFound)來表示這些類型不存在的狀況。Swift的選項可讓咱們表示任何類型都沒有值的狀況,而不須要特殊的常量。
對於非可選類型的常量或變量咱們不能使用nil,若是咱們的代碼須要在變量或常量缺乏值的狀況下正常運行,那麼咱們就應該始終聲明變量或變量爲相應類型的可選值 在不提供默認值的狀況下定義可選變量var str: String?
系統將會自動爲變量設置nil
,Swift中的nil與Objective-C不一樣。在Objective-C中,nil
是一個指向不存在的對象的指針。在Swift中,nil
不是指針,而是一個肯定的類型的變量或常量的一個缺省值。任何類型的可選值都能設置nil
,不只僅只是對象類型
if語句和強制解包:
使用if語句經過「等於」運算符(==
)或「不等於」運算符(!=
)比較可選項,來肯定可選項是否包含值nil
。
let possibleNumber = "123"
let convertedNumber : Int? = Int(possibleNumber)
if convertedNumber != nil {
//! 當咱們肯定了convertedNumber的值不可能爲nil即可以使用!進行強制解包獲取可選包中的值
print(convertedNumber!)
複製代碼
強制解包可選的值:一旦肯定可選項確實包含值,就能夠經過在可選項名稱的末尾添加感嘆號!
來訪問其基礎值。
可選綁定: 使用可選綁定
來肯定可選項是否包含值,若是包含值,則這個值可用於臨時常量或變量的值。可選綁定
可與if和while語句一塊兒使用,以檢查可選內部的值,並將該值提取爲常量或變量,做爲單個操做的一部分。 可選綁定,if語句示例
let possibleNumber = "1234"
let convertedNumber : Int? = Int(possibleNumber)
if let tempValue = convertedNumber {
print(tempValue);
} else {
print("沒有值")
}
if var tempVar = convertedNumber {
tempVar = tempVar + 1
print(tempVar);
} else {
print("沒有值")
}
複製代碼
代碼解讀:若是Int類型的可選項convertedNumber ,經過Int(possibleNumber)返回了一個值,則使用此值設置一個新的常量tempValue。條件成立時,tempValue是被一個沒有可選包的肯定的值初始化的,所以沒有必要使用!
後綴來訪問它的值。
單個if語句中能夠包含儘量多的可選綁定
和布爾條件
,並以逗號分隔。若是可選綁定
中的任何值是nil,或任何布爾條件求值爲false,則整個語句的條件是false。示例:
if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
print("\(firstNumber) < \(secondNumber) < 100")
} else {
print("不成立")
}
//等效的表達形式
if let firstNumber = Int("4") {
if let secondNumber = Int("42") {
if firstNumber < secondNumber && secondNumber < 100 {
print("\(firstNumber) < \(secondNumber) < 100")
}
}
}
複製代碼
隱式解包(未包裝)的可選項:
可選項:容許咱們的常量或變量不存在,使用時,可使用if 語句檢查是否nil
或者使用可選綁定
進行解包,以保證可選項在有值得狀況下正確的訪問值。
隱式解包(未包裝)的可選項:咱們從程序的結構能夠得出,在咱們首次設置可選項的值之後,這個可選項將老是會有值,每次調用都不多是nil
。基於此咱們可能會想,那麼咱們就不必每次訪問值時,都檢查和解包可選的值。那麼上述場景中可選項,即可以被定義爲隱式解包(未包裝)的可選項。 可選類型的定義是類型後加?
:(String?),而隱式解包的可選項是在類型後加!
:(String!)
隱式解包的可選項幕後實際上是一個正常的可選項,可是咱們能夠像非可選值那樣去使用,而不用每次訪問都要先對可選項的值解包。
當使用一個字符串類型的可選項和一個隱式解包的字符串類型的可選項去訪問它們字符串類型可選包(wrapped)中的肯定值會有差別。
1.定義了字符串類型的可選項,並賦初值。在使用時須要針對可選的字符串,進行強制解包,以獲取其中的肯定值。須要加!
。
//! 1.定義了字符串類型的可選項,並賦初值。
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // 使用時須要針對可選的字符串,進行強制解包,以獲取其中的肯定值。
複製代碼
2.定義了隱式解包的字符串類型的可選項,並賦初始值。使用時,不在須要針對隱式解包的字符串類型的可選項,進行解包。再也不須要!
//! 2.定義了隱式解包的字符串類型的可選項,並賦初始值。
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // 使用時,不在須要針對隱式解包的字符串類型的可選項,進行解包 即:再也不須要!
複製代碼
3.若是隱式解包的可選項是nil
而且嘗試訪問其包裝值,則會觸發運行時錯誤。結果與在不包含值的普通可選項以後放置感嘆號徹底相同。同時也能夠將隱式解包的可選項視爲普通可選項,以檢查它是否包含值:if
或可選綁定
。
let assumedString: String! = nil
let implicitString: String = assumedString
print(implicitString)//!< 崩潰:隱式解包一個可選項的值時發現了nil。Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
複製代碼
錯誤處理: 響應程序在執行期間可能遇到的錯誤狀況。 定義能夠拋出錯誤的函數
func canThrowAnError() throws {
// this function may or may not throw an error
}
複製代碼
函數聲明時在參數與返回值之間使用關鍵字throws
,表明這個函數可能拋出錯誤。在調用這個可能拋出錯誤函數時須要在表達式前放置try
關鍵字。
當使用catch分句處理錯誤時,Swift會自動把函數拋出的錯誤,自動傳播出當前的函數做用域。
do {
try canThrowAnError()
// no error was thrown
} catch {
// an error was thrown
}
複製代碼
如下是如何使用錯誤處理來響應不一樣錯誤條件的示例:
1.定義錯誤
Error
類型:表示一個可以被拋出(thrown)的錯誤。聲明的任何類型只要遵照了 Error
的協議都可以在Swift的錯誤處理系統中表示一個錯誤。由於Error
協議沒有要求自身必須實現,咱們能夠在建立的任何自定義類型中聲明遵照這個協議便可。
public protocol Error {
}
extension Error {
}
extension Error where Self : RawRepresentable, Self.RawValue : FixedWidthInteger {
}
複製代碼
Error
枚舉:Swift的枚舉很適合表示簡單的錯誤。咱們能夠建立一個遵照Error
協議的枚舉類型,並在枚舉中定義每一種可能的錯誤事例。
enum HttpError: Error {
case authError
case netWorkError
case serviceError
}
複製代碼
2.定義方法
func requestWebData(status: String) throws -> Void {
let status = status
if status == "401" {
throw HttpError.authError
} else if status == "500" {
throw HttpError.serviceError
} else if status == "404"{
throw HttpError.netWorkError
} else {
print("一切正常");
}
}
func noThrowErrorCanDoSomeThing () {
print("沒有錯誤拋出,能夠作咱們要作的事情")
}
func handleServiceError() {
print("服務器錯誤,須要從新鏈接")
}
func handleAuthError () throws {
print("受權失敗了,選擇從新登陸")
//! 網絡請求
do {
try requestWebData(status: "404")
} catch let error as HttpError {
throw error
}
}
func handleNetWorkError(){
print("網絡錯誤了,檢查網絡")
}
複製代碼
3.使用do try catch
方法調用並處理異常。
do {
try requestWebData(status:"400")
//沒有出現錯誤,作事情
noThrowErrorCanDoSomeThing()
} catch HttpError.authError {
do {
try handleAuthError()
} catch HttpError.netWorkError {
print("受權登陸時出現網絡錯誤")
} catch {
print("受權登陸時出現其餘錯誤")
}
} catch HttpError.netWorkError {
handleNetWorkError()
} catch HttpError.serviceError {
handleServiceError()
} catch {
print("其餘錯誤")//!< 這個catch就是在補全錯誤的處理,不然編譯器指示錯誤
}
複製代碼
斷言和前置條件:
在執行任何進一步的代碼以前,使用它們來確保代碼知足基本條件。若是斷言或前置條件中的布爾條件求值爲true,則代碼執行將照常繼續。若是條件評估爲false,則程序的當前狀態無效,代碼執行結束,程序終止。 斷言:只有debug
環境下才能夠生效。 1.代碼未進行條件檢查
let num = -1
assert(num > 0, "num不能爲負數")
複製代碼
2.代碼進行了條件檢查
let num = -1
if num > 10 {
} else if num >= 0 {
} else {
assertionFailure("num不能爲負數")//!< 陳述條件的信息
}
複製代碼
前置條件:在release
環境下也能夠生效。
let num = -1
precondition(num > 0, "num不能爲負數")
複製代碼
注意:
let
關鍵字將其聲明爲常量。存儲須要更改的值須要始終使用var
關鍵字將其聲明爲變量。var str1 : String
則須要提供類型註釋UInt
。其餘狀況Int
則優選,即便已知要存儲的值是非負的。Int
對整數值的一導致用有助於代碼互操做性,避免在不一樣數字類型之間進行轉換,有利於整數類型推斷。Double
至少能夠精確到小數點後15位,Float
的精度能夠少至6位小數。任何一種類型適當的狀況下,Double
是首選。代碼中也能夠根據使用的值的性質和範圍選擇適當浮點類型。!
訪問不存在的可選值會觸發運行時錯誤。在使用!
強制解包可選變量或常量的值以前,請務必確保可選項包含的值非nil
。可選綁定
建立的常量和變量僅在if語句的主體中可用。相反,使用guard語句建立的常量和變量在主體語句後面的代碼行中仍然可用。let possibleNumber = "1234"
let convertedNumber : Int? = Int(possibleNumber)
guard let tempValue = convertedNumber else {
print("沒有值")
//只是跳出方法體
return
}
print("guard\(tempValue)")
複製代碼
nil
,請始終使用普通的可選類型。var assumedString: String! = "俺是張飛"
assumedString = nil;
let implicitString: String = assumedString //< 崩潰:隱式解包一個可選項的值時發現了nil。Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
複製代碼
參考資料: swift 5.1官方編程指南
小編微信:可加並拉入《QiShare技術交流羣》。
關注咱們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公衆號)
推薦文章:
iOS UI狀態保存和恢復(三)
iOS UI狀態保存和恢復(二)
iOS UI狀態保存和恢復(一)
iOS 中精肯定時的經常使用方法
Sign In With Apple(一)
算法小專欄:動態規劃(一)
Dart基礎(一)
Dart基礎(二)
Dart基礎(三)
Dart基礎(四)
奇舞週刊