【Swift官方助讀】 重讀Swift

  1. 枚舉的成員值是實(shí)際值,并不是原始值的另一種表達(dá)方法。 可以嘗試打印生成的枚舉就是該值本身,而打印rawValue后才是對應(yīng)的type的值

  2. 處理錯(cuò)誤:
    1 Throw Throws Do Catch
    2 try?
    將結(jié)果轉(zhuǎn)換為可選的。如果函數(shù)拋出錯(cuò)誤,該錯(cuò)誤會被拋棄并且結(jié)果為nil。否則的話,結(jié)果會是一個(gè)包含函數(shù)返回值的可選值。

1 第一種方式
enum myError: Error{
    
    case OutOfPaper
    case NoToner
    case OnFire
}

func sendToPrinter(pointerName: String) throws -> String {
    
    if pointerName == "NeverHasToner" {
        throw myError.NoToner
    }
    
     defer {
        print("不管方法是否被throw拋錯(cuò)阻止都會走進(jìn)來 defer是函數(shù)終止前執(zhí)行的最后一段代碼 不因throw而影響")
    }
    
    return "Yes It is me"
}

do {
     let valueThrowing = try sendToPrinter(pointerName: "NeverHasToner")
    print(valueThrowing)
    
} catch myError.OnFire {
    print("Catch的東西就是你throw出來的東西 因此你可以進(jìn)行判斷和自定義")
}
catch let myOwnErrorNow as myError {
    print("我自己的錯(cuò)誤類型**********\(myOwnErrorNow)")
}
catch {
    print("系統(tǒng)默認(rèn)的錯(cuò)誤類型********\(error)")
}

2 第二種方式
let canThrowError = try? sendToPrinter(pointerName: "NeverHasToner---")
let canThrowError = try? sendToPrinter(pointerName: "NeverHasToner")

3 與系統(tǒng)關(guān)鍵字沖突時(shí)使用 let let = "dkfjdkfj"; print(let)

4 浮點(diǎn)類型 Float

浮點(diǎn)字面量可以是十進(jìn)制(沒有前綴)或者是十六進(jìn)制(前綴是 0x )。小數(shù)點(diǎn)兩邊必須有至少一個(gè)十進(jìn)制數(shù)字(或者是十六進(jìn)制的數(shù)字)。十進(jìn)制浮點(diǎn)數(shù)也可以有一個(gè)可選的指數(shù)(exponent),通過大寫或者小寫的 e 來指定;十六進(jìn)制浮點(diǎn)數(shù)必須有一個(gè)指數(shù),通過大寫或者小寫的 p 來指定。

如果一個(gè)十進(jìn)制數(shù)的指數(shù)為 exp,那這個(gè)數(shù)相當(dāng)于基數(shù)和10^exp的乘積:

1.25e2 表示 1.25 × 10^2,等于 125.0。
1.25e-2 表示 1.25 × 10^-2,等于 0.0125。
如果一個(gè)十六進(jìn)制數(shù)的指數(shù)為exp,那這個(gè)數(shù)相當(dāng)于基數(shù)和2^exp的乘積:

0xFp2 表示 15 × 2^2,等于 60.0。
0xFp-2 表示 15 × 2^-2,等于 3.75。

5 斷言保證前面的表達(dá)式必須要通過 不然后面就會是表達(dá)式 assert(1 > 2, "Imposible")

6 Swift 的String類型是基于 Unicode 標(biāo)量 建立的。 Unicode 標(biāo)量是對應(yīng)字符或者修飾符的唯一的21位數(shù)字.Unicode 標(biāo)量,寫成\u{n}(u為小寫),其中n為任意一到八位十六進(jìn)制數(shù)且可用的 Unicode 位碼。let sparklingHeart = "\u{1F496}" // ??, Unicode 標(biāo)量 U+1F496

7 字符串的標(biāo)量

每一個(gè) Swift 的Character類型代表一個(gè)可擴(kuò)展的字形群。 一個(gè)可擴(kuò)展的字形群是一個(gè)或多個(gè)可生成人類可讀的字符 Unicode 標(biāo)量的有序排列。 舉個(gè)例子,字母é可以用單一的 Unicode 標(biāo)量é(LATIN SMALL LETTER E WITH ACUTE, 或者U+00E9)來表示。然而一個(gè)標(biāo)準(zhǔn)的字母e(LATIN SMALL LETTER E或者U+0065) 加上一個(gè)急促重音(COMBINING ACTUE ACCENT)的標(biāo)量(U+0301),這樣一對標(biāo)量就表示了同樣的字母é。 這個(gè)急促重音的標(biāo)量形象的將e轉(zhuǎn)換成了é。在這兩種情況中,字母é代表了一個(gè)單一的 Swift 的Character值,同時(shí)代表了一個(gè)可擴(kuò)展的字形群。 在第一種情況,這個(gè)字形群包含一個(gè)單一標(biāo)量;而在第二種情況,它是包含兩個(gè)標(biāo)量的字形群: 但無論怎樣在 Swift 都會表示為同一個(gè)單一的Character值

8 想要獲得一個(gè)字符串中Character值的數(shù)量,可以使用字符串的characters屬性的count屬性。在 Swift 中,使用可拓展的字符群集作為Character值來連接或改變字符串時(shí),并不一定會更改字符串的字符數(shù)量。所以字符在一個(gè)字符串中并不一定占用相同的內(nèi)存空間數(shù)量。通過characters屬性返回的字符數(shù)量并不總是與包含相同字符的NSString的length屬性相同。NSString的length屬性是利用 UTF-16 表示的十六位代碼單元數(shù)字,而不是 Unicode 可擴(kuò)展的字符群集。作為佐證,當(dāng)一個(gè)NSString的length屬性被一個(gè)Swift的String值訪問時(shí),實(shí)際上是調(diào)用了utf16Count。

var word = "cafe"
print("the number of characters in \(word) is \(word.characters.count)")
// 打印輸出 "the number of characters in cafe is 4"
word += "\u{301}"    // COMBINING ACUTE ACCENT, U+0301
print("the number of characters in \(word) is \(word.characters.count)")
// 打印輸出 "the number of characters in café is 4"

9 使用startIndex屬性可以獲取一個(gè)String的第一個(gè)Character的索引。使用endIndex屬性可以獲取最后一個(gè)Character的后一個(gè)位置的索引。因此,endIndex屬性不能作為一個(gè)字符串的有效下標(biāo)。如果String是空串,startIndex和endIndex是相等的。

10 Unicode String的等與不等

如果兩個(gè)字符串(或者兩個(gè)字符)的可擴(kuò)展的字形群集是標(biāo)準(zhǔn)相等的,那就認(rèn)為它們是相等的。在這個(gè)情況下,即使可擴(kuò)展的字形群集是有不同的 Unicode 標(biāo)量構(gòu)成的,只要它們有同樣的語言意義和外觀,就認(rèn)為它們標(biāo)準(zhǔn)相等??梢杂?== 或 != 來比較

11 默認(rèn)參數(shù)可以是一個(gè)方法里的任意一個(gè)

func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12, parameThree: Int) {
    
}

someFunction(parameterWithoutDefault: 4, parameThree: 1)

12 一個(gè)函數(shù)最多只能擁有一個(gè)可變參數(shù), 參數(shù)位置在哪為所謂

13 閉包表達(dá)式的參數(shù)可以是inout參數(shù),但不能設(shè)定默認(rèn)值。也可以使用具名的可變參數(shù)(譯者注:但是如果可變參數(shù)不放在參數(shù)列表的最后一位的話

14 逃逸閉包(Escaping Closures)

當(dāng)一個(gè)閉包作為參數(shù)傳到一個(gè)函數(shù)中,但是這個(gè)閉包在函數(shù)返回之后才被執(zhí)行,我們稱該閉包從函數(shù)中逃逸。當(dāng)你定義接受閉包作為參數(shù)的函數(shù)時(shí),你可以在參數(shù)名之前標(biāo)注 @escaping,用來指明這個(gè)閉包是允許“逃逸”出這個(gè)函數(shù)的。一種能使閉包“逃逸”出函數(shù)的方法是,將這個(gè)閉包保存在一個(gè)函數(shù)外部定義的變量中。舉個(gè)例子,很多啟動異步操作的函數(shù)接受一個(gè)閉包參數(shù)作為 completion handler。這類函數(shù)會在異步操作開始之后立刻返回,但是閉包直到異步操作結(jié)束后才會被調(diào)用。在這種情況下,閉包需要“逃逸”出函數(shù),因?yàn)殚]包需要在函數(shù)返回之后被調(diào)用.將一個(gè)閉包標(biāo)記為 @escaping 意味著你必須在閉包中顯式地引用 self.

var completionHandlers: [() -> Void] = []

func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

func someFunctionWithNonescapingClosure(closure: () -> Void) {
    closure()
}

class SomeClass {
    var x = 10
    func doSomething() {
        someFunctionWithEscapingClosure { self.x = 100 }
        someFunctionWithNonescapingClosure { x = 200 }
    }
}

let instance = SomeClass()
instance.doSomething()
print(instance.x)
// 打印出 "200"

completionHandlers.first?()
print(instance.x)
// 打印出 "100"

15 @autoclosure

對閉包參數(shù)的一種修飾。表明該閉包不接受任何參數(shù),當(dāng)它被調(diào)用的時(shí)候,會返回被包裝在其中的表達(dá)式的值。因此在調(diào)用該函數(shù)傳值時(shí)就只需要傳以前的閉包中的表達(dá)式而非整個(gè)表達(dá)式閉包。

var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

// customersInLine is ["Barry", "Daniella"]
var customerProviders: [() -> String] = []
func collectCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {
    customerProviders.append(customerProvider)
}
collectCustomerProviders(customersInLine.remove(at: 0))
collectCustomerProviders(customersInLine.remove(at: 0))

print("Collected \(customerProviders.count) closures.")
// 打印出 "Collected 2 closures."
for customerProvider in customerProviders {
    print("Now serving \(customerProvider())!")
}
// 打印出 "Now serving Barry!"
// 打印出 "Now serving Daniella!"

16 在使用原始值為整數(shù)或者字符串類型的枚舉時(shí),不需要顯式地為每一個(gè)枚舉成員設(shè)置原始值,Swift 將會自動為你賦值。當(dāng)使用整數(shù)作為原始值時(shí),隱式賦值的值依次遞增1。如果第一個(gè)枚舉成員沒有設(shè)置原始值,其原始值將為0。當(dāng)使用字符串作為枚舉類型的原始值時(shí),每個(gè)枚舉成員的隱式原始值為該枚舉成員的名稱。

17 遞歸枚舉

遞歸枚舉(recursive enumeration)是一種枚舉類型,它有一個(gè)或多個(gè)枚舉成員使用該枚舉類型的實(shí)例作為關(guān)聯(lián)值。使用遞歸枚舉時(shí),編譯器會插入一個(gè)間接層。你可以在枚舉成員前加上indirect來表示該成員可遞歸。

enum ArithmeticExpression {
    case number(Int)
    indirect case addition(ArithmeticExpression, ArithmeticExpression)
    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}

//或者統(tǒng)一寫到外面 indirect
indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, ArithmeticExpression)
}

let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))

func evaluate(_ expression: ArithmeticExpression) -> Int {
    switch expression {
    case let .number(value):
        return value
    case let .addition(left, right):
        return evaluate(left) + evaluate(right)
    case let .multiplication(left, right):
        return evaluate(left) * evaluate(right)
    }
}

print(evaluate(product))
// 輸出 "18"

18 文檔注釋說明

/// 求和
/// - parameter 參數(shù)1: 參數(shù)1說明
/// - returns: 返回值

未完待續(xù) 歡迎點(diǎn)擊愛心

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容