Swift之旅_Language Guide1
最近抽空閱讀了swift官方文件的Language Guide部分小節,下面記錄一些知識盲點和個人認為比較有用的東西。
The Basics
第一個小節主要講解了一些基本的東西,如var let等。也有一些知識點可以記錄一下吧。
-
typealias
相當於oc裡的tyepdef吧,可以用來取別名。
typealias AudioSample = UInt16
-
optional & nil
Swift’s nil isn’t the same as nil in Objective-C. In Objective-C, nil is a pointer to a nonexistent object. In Swift, nil isn’t a pointer—it’s the absence of a value of a certain type. Optionals of any type can be set to nil, not just object types.
大概的意思是說oc裡的nil是指向了一個不存在的物件,而在swift中,nil不是指標,它是一個確定型別的缺失(= =蹩腳的英文),任何可選型別可以設定成nil,不只是物件型別。網上也有很多資料都介紹過可選型別,可選其實就是對某個型別進行了一層包裝,裡面包含了some和none,none就是這個nil,some就是具體的值。
-
assert:斷言
大部分用來除錯使用,類似guard,但是不符合條件程式會直接退出。
let age = -3
assert(age >= 0, "A person's age can't be less than zero.")
-
Error handle
異常處理,不過目前只在呼叫別人的api的時候用到過= =。
do {
try caThrowAnError(age: 1000)
} catch AgeEorror.negative {
print(AgeEorror.negative.rawValue)
} catch AgeEorror.tooLarge {
print(AgeEorror.tooLarge.rawValue)
} catch {
print("未知錯誤~")
}
enum AgeEorror: String, Error {
case negative = "輸入的年齡不能是負數!"
case tooLarge = "不可能活那麼久!"
}
func caThrowAnError(age: Int) throws {
if age < 0 {
throw AgeEorror.negative
} else if age > 200 {
throw AgeEorror.tooLarge
}
}
這裡結合列舉使用,丟擲的錯誤型別必須遵循Error協議。
Basic Operators
這一小節比較簡單,講解了大部分操作符。相信有點程式設計基礎的應該都會一眼帶過,但也抽兩個知識點意思意思吧!
-
??
這個操作符在平時開發中使用還是非常頻繁的,至少本人平時經常使用,有點像是三目運算子的感覺。
var a: Int?
let b = a ?? 0
如上程式碼,大致的意思就是假設a有值,即a不為nil的時候會把a賦值給b,如果a為nil則把0賦值給b。
-
區間運算子[...]
這個操作符在遍歷集合等場景使用較多。
let names = ["1","2","3","4","5"]
for name in names[...3] {
print(name)
}
沒錯,就是你心裡想的那樣,遍歷第0-3個元素,也可以加入<操作符,如[..<3]表示遍歷第0,1,2個元素。
Strings and Characters
這一小節主要是講解了Swift中的字串,有幾個知識點在上一篇文章Swift之旅_Welcome to Swift有提到過,主要是一個字串可以用”””來表示多行,還有新增了一個Substring型別,具體的可以參考上一篇文章。
Collection Types
這一小節講解的是Swift中的集合型別,主要是Array,Dictionary,Set。都比較簡單,而且Swift中用起來很方便。但是因為Set平時用的很少,我就著重看了一下。
A type must be hashable in order to be stored in a set—that is, the type must provide a way to compute a hash value for itself. A hash value is an Int value that is the same for all objects that compare equally, such that if a == b, it follows that a.hashValue == b.hashValue.
Set是一個無序不重複的集合,Set中的元素必須是可雜湊的。直接一直不知道雜湊是什麼鬼。最近一次學習的時候知道了雜湊其實就是一個單向雜湊函式。單項雜湊函式可以將一串資料計算得到一個獨一無二的值,所以也不難理解為啥Set中的元素必須是可雜湊的了,因為Set是不重複的。
Set集合中一些常用的操作和對應的效果,官方文件中的這幅圖非常形象。
Control Flow
控制流,講解了一些迴圈和控制語句。
-
for迴圈
常見的都很簡單,不過文件中倒是提到了一種比較特別的迴圈方式,可以以一個數的倍數進行迴圈:
let minutes = 60
let minuteInterval = 5
for tickMark in stride(from: 0, to: minutes, by: minuteInterval) {
// render the tick mark every 5 minutes (0, 5, 10, 15 ... 45, 50, 55)
}
//以下寫法可以到達hours,相當於小於等於吧
let hours = 12
let hourInterval = 3
for tickMark in stride(from: 3, through: hours, by: hourInterval) {
// render the tick mark every 3 hours (3, 6, 9, 12)
}
此外我們都知道Swift中的switch語句是不用手動寫break的,Swift也提供了一個修飾符可以讓switch像c一樣, fallthrough,這個修飾符可以讓swift的switch語句匹配到對應的值之後繼續向下落。
let a = 5
switch a {
case 5,6,7,8,9:
print("case 1")
fallthrough
case 1,2,3,4,5:
print("case 2")
fallthrough
default:
print("default")
}
Functions
這個小節就比較重要了,講解的是Swift中的函式。
-
Variadic Parameters-可變引數
可變引數在絕對大多數開發語言中都存在,Swift也不列外。Swift中使用可變引數也是非常簡單。
func arithmeticMean(_ numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8.25, 18.75)
// returns 10.0, which is the arithmetic mean of these three numbers
-
In-Out Parameters
在函式內部是無法直接更改引數的值的,或者這樣說比較貼切,引數在函式內部是let形式的。若想要達到更改呼叫函式時傳入的引數就需要用到inout這個修飾符。
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
Closures
block的作用和oc的大致相同,但是這裡有多個注意點。
-
$0
Swift中的block可以直接用$0,$1...表示第1,2…引數,這樣可以直接不用寫明引數 和 in,這樣寫起來程式碼似乎是清爽了很多。
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
reversedNames = names.sorted(by: { $0 > $1 } )
-
可以直接將函式賦值給block
只要引數和返回值都相同,就可以直接將函式賦值給block
var block: (()->Int) = test
func test() -> Int {
return 0
}
-
Escaping Closures
逃逸閉包,相信很多同學都碰到過Xcode自動幫你在函式引數中的block前面加上@escaping修飾符。
A closure is said to escape a function when the closure is passed as an argument to the function, but is called after the function returns. When you declare a function that takes a closure as one of its parameters, you can write @escaping before the parameter’s type to indicate that the closure is allowed to escape.
當閉包作為函式引數傳遞,但是是在函式返回後呼叫時,閉包被稱為逃逸閉包。當你宣告一個有閉包引數的函式時,你可以在引數前面寫上@escaping表明閉包時允許逃逸的。
One way that a closure can escape is by being stored in a variable that is defined outside the function. As an example, many functions that start an asynchronous operation take a closure argument as a completion handler. The function returns after it starts the operation, but the closure isn’t called until the operation is completed—the closure needs to escape, to be called later.For example:
閉包可以逃避的一種方法是儲存在函式之外定義的變數中。例如,啟動非同步操作的許多函式都使用閉包引數作為完成回撥。函式在啟動操作後返回,但是在操作完成之前不會呼叫閉包-為了可以延遲呼叫,閉包需要時可逃逸的。例如:
var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
completionHandlers.append(completionHandler)
}
The someFunctionWithEscapingClosure(_:) function takes a closure as its argument and adds it to an array that’s declared outside the function. If you didn’t mark the parameter of this function with @escaping, you would get a compile-time error.
someFunctionWithEscapingClosure函式有一個閉包引數並且把它新增到了函式外部的一個陣列中。如果你不在函式引數前面加上@ escaping,你會在編譯的時候得到一個error。
其實大概的意思就是如果這個block是作為函式引數使用,並且是在函式執行完畢之後呼叫的,就需要在函式的block引數前面加上@escaping修飾符。其實這個大多時候XCode幫我們做了。大家瞭解一下就行。
-
@autoclosure
這個原文有點難翻譯= =,直接上一段程式碼吧。
func test3(tBlock: @autoclosure ()->String) {
print(tBlock())
}
test3(tBlock: "World")
大概意思就是和程式碼一樣吧,感覺就是加上@autoclosure之後,呼叫函式的時候可以直接傳入和閉包返回值相同型別的引數。
相關文章
- 【讀書筆記】The Swift Programming Language (Swift 4.0.3)筆記Swift
- 死磕The Swift Programming Language——學Swift
- The Swift Programming Language 中文版Swift
- 《The Swift Programming Language》中文版翻譯完成Swift
- “Use Legacy Swift Language Version” (SWIFT_VERSION) is required to be configured 這個錯誤解決方案SwiftUI
- [譯]《The Swift Programming Language》2 0版之自動引用計數Swift
- 開啟你的Swift伺服器之旅-Perfect框架Swift伺服器框架
- The Go Programming LanguageGo
- the java programming languageJava
- Google分析language垃圾資訊Go
- (C language Sample ) Compile procedureCompile
- Domino XML Language(DXL)簡介XML
- yaml (YAML Ain't Markup Language)YAMLAI
- Html language common symbolic entitiesHTMLSymbol
- [Paper Reading] KOSMOS: Language Is Not All You Need: Aligning Perception with Language Models
- golang programming language study methods websocketGolangWeb
- R language notes | pipes: chainingAI
- MySQL - DDL詳解(Data Definition Language)MySql
- ECMAScript® 2015 Language Specification
- lambda expressions are not supported at this language level intellijExpressIntelliJ
- 不做“語言律師”(language lawyers)
- Hugo 之旅Go
- SwiftSwift
- MySQL-DML(Data Manipulation Language)詳解MySql
- SQL language裡面的經典問題SQL
- Go之旅-SwitchGo
- Go之旅-常量Go
- Redux之旅-1Redux
- NOSQL之旅---HBaseSQL
- 探索之旅
- 【譯】回顧Swift 3, 展望Swift 4Swift
- The Overview of ECMA C# Language Specialisation (2) (轉)ViewC#
- The Overview of ECMA C# Language Specialisation (1) (轉)ViewC#
- .NET Framework 之 Common Language Runtime (轉)Framework
- Realm for SwiftSwift
- DispatchQueue swiftSwift
- Swift,字串Swift字串
- Swift,集合Swift