Swift學習筆記 (四十三) 詞法結構

關鍵字和標點符號

下⾯這些被保留的關鍵字不允許用作標識符,除非使用反引號轉義,具體描述請參考《標識符》。除了 inout 、 var 以及 let 之外

的關鍵字可以用作某個函數聲明或者函數調用當中的外部參數名,無需添加反引號轉義。當一個成員與一個關鍵字具有相同的名

稱時,不需要使用反引號來轉義對該成員的引用,除非在引用該成員和使用該關鍵字之間存在歧義 - 例如, self , Type 和 

Protocol 在顯式的成員表達式中具有特殊的含義,因此它們必須在該上下文中使用反引號進⾏轉義。

用在聲明中的關鍵字:

 associatedtype 、 class 、 deinit 、 enum 、 extension 、 fileprivate 、 func 、 import 、 init 、 inout 、 internal 、 let 、

open 、 operator 、 private 、 protocol 、 public 、 static、 struct 、 subscript 、 typealias 以及 var 。

用在語句中的關鍵字: 

break 、 case 、 continue 、 default 、 defer 、 do 、 else 、 fallthrough 、 for 、 guar d、if、in、repeat、return、switch、

where 以及 while。

用在表達式和類型中的關鍵字: 

as 、 Any 、 catch 、 false 、 is 、 nil 、 rethrows 、 super 、 self 、 Self 、 throw 、throws 、 true 以及 try 。

用在模式中的關鍵字: _ 。

以井字號( # )開頭的關鍵字:

 #available 、 #colorLiteral 、 #column 、 #else 、 #elseif 、 #endif 、 #error 、 #file、 #fileLiteral 、 #function 、 #if 、 

#imageLiteral 、 #line 、 #selector 、 #sourceLocation以及 #warning 。

特定上下⽂中被保留的關鍵字:

associativity 、 convenience 、 dynamic 、 didSet 、 final 、 get 、 infix 、 indirect 、 lazy 、 left 、 mutating 、 none 、 

nonmutating 、 optional 、 override 、 postfix 、 precedence、 prefix 、 Protocol 、 required 、 right 、 set 、 Type 、 

unowned 、 weak 以及 willSet 。 這些關鍵字在特定上下文之外可以被用做標識符。

以下符號被當作保留符號,不能用於自定義運算符:

( 、 ) 、 { 、 } 、 [ 、 ] 、 . 、 , 、 : 、 ; 、 = 、 @ 、 # 、 & (作爲前綴運算符)、 -> 、 ` 、 ? 、 ! (作爲後綴運算符)。

 

字面量

字⾯量(literal) 用來表示源碼中某種特定類型的值,⽐如一個數字或字符串。

下⾯是字面量的一些示例:

42                              // 整數字⾯量

3.14159                     // 浮點數字⾯量

"Hello, world!"          // 字符串字⾯量

true                           // 布爾值字面量

字⾯量本身並不包含類型信息。事實上,一個字⾯量會被解析爲擁有無限的精度,然後 Swift 的類型推導會嘗試去推導出這個字

⾯量的類型。⽐如,在 let x: Int8 = 42 這個聲明中,Swift 使用了顯式類型註解( : Int8 )來推導出 42 這個整數字⾯量的類型是 

Int8 。如果沒有可用的類型信息, Swift 則會從標準庫中定義的字⾯量類型中推導出一 個默認的類型。整數字⾯量的默認類型是 

Int ,浮點數字⾯量的默認類型是 Double ,字符串字⾯量的默認類型是 String ,布爾值字⾯量的默認類型是 Bool 。比如,在 

let str = "Hello, world" 這個聲明中,字符串"Hello, world" 的默認推導類型就是 String 。

當爲一個字⾯量值指定了類型註解的時候,這個標註的類型必須能通過這個字⾯量值實例化。也就是說,這個類型必須符合這些

Swift 標準庫協議中的一個:整數字⾯量的 IntegerLiteralConvertible 協議、浮點數字⾯量的 FloatingPointLiteralConvertible 

協議、字符串字⾯量的 StringLiteralConvertible 協議以及布爾值字⾯量的 BooleanLiteralConvertible 協議。比如, Int8 符合 

IntegerLiteralConvertible 協議,因此它能在 let x: Int8 = 42 這個聲明中作爲整數字⾯量 42 的類型註解。

 

整數字面量

整數字⾯量(Integer Literals) 表示未指定精度整數的值。整數字⾯量默認用十進制表示,可以加前綴來指定其他的進制。二進制

字⾯量加 0b ,⼋進制字⾯量加 0o ,十六進制字⾯量加 0x 。

十進制字⾯量包含數字 0 ⾄ 9 。⼆進制字⾯量只包含 0 或 1 ,八進制字⾯量包含數字 0 至 7 ,十六進制字⾯量包含數字 0 至 9 

以及字母 A ⾄ F (⼤小寫均可)。

負整數的字⾯量在整數字⾯量前加負號 - ,比如 -42 。

整型字⾯量可以使用下劃線( _ )來增加數字的可讀性,下劃線會被系統忽略,因此不會影響字⾯量的值。同樣地,也可以在數字

前加 0 ,這同樣也會被系統所忽略,並不會影響字⾯量的值。 除⾮特別指定,整數字⾯量的默認推導類型爲 Swift 標準庫類型中

的 Int 。Swift 標準庫還定義了其他不同長度以及是否帶符號的整數類型。

 

浮點數字⾯量

浮點數字⾯量(Floating-point literals) 表示未指定精度浮點數的值。 浮點數字⾯量默認用十進制表示(無前綴),也可以用十六進制

表示(加前綴 0x )。

十進制浮點數字⾯量由十進制數字串後跟小數部分或指數部分(或兩者皆有)組成。⼗進制小數部分由小數點( . )後跟十進制數字串

組成。指數部分由大寫或小寫字母 e 爲前綴後跟十進制數字串組成,這串數字表示 e 之前的數量乘以 10 的幾次方。例如: 1.25e2 

表示 1.25 x 10的2次方,也就是 125.0 ;同樣, 1.25e-2 表示 1.25 x 10的負2次方,也就是0.0125 。

十六進制浮點數字⾯量由前綴 0x 後跟可選的十六進制小數部分以及十六進制指數部分組成。十六進制小數部分由小數點後跟⼗

六進制數字串組成。指數部分由大寫或小寫字母 p 爲前綴後跟十進制數字串組成,這串數字表示 p 之前的數量乘以 2 的幾次⽅

方。例如: 0xFp2 表示 15 x 2的2次方,也就是 60 ;同樣, 0xFp-2 表示 15 x 2的負2次方,也就是 3.75 。

負數的浮點數字⾯量由負號( - )和浮點數字⾯量組成,例如 -42.5 。

浮點數字⾯量允許使用下劃線( _ )來增強數字的可讀性,下劃線會被系統忽略,因此不會影響字⾯量的值。同樣地,也可以在數

字前加 0 ,並不會影響字⾯量的值。

除⾮特別指定,浮點數字⾯量的默認推導類型爲 Swift 標準庫類型中的 Double ,表示 64 位浮點數。Swift 標準庫也定義了 Float 

類型,表示 32 位浮點數。

 

字符串字面量

字符串字⾯量是被引號包括的一串字符組成。 單⾏字符串字⾯量被包在雙引號中的一串字符組成,形式如下:

" 字符 "

字符串字⾯量中不能包含未轉義的雙引號( " )、未轉義的反斜線( \ )、回⻋符、換⾏符。 多⾏字符串字⾯量被包在三個雙引號中

的一串字符組成,形式如下:

""" 字符 """

與單⾏字符串字⾯量不同的是,多⾏字符串字⾯量可以包含不轉義的雙引號("),回⻋以及換行。它不能包含三個未轉義的連續雙

引號。

""" 之後的回車或者換⾏開始多⾏字符串字⾯量,不是字符串的一部分。 """ 之前回車或者換⾏結束字⾯量,也不是字符串的一部

分。要讓多⾏字符串字⾯量的開始或結束帶有換行,就在第一⾏或者最後⼀⾏寫⼀個空行。

多⾏字符串字⾯量可以使⽤任何空格或製表符組合進⾏縮進;這些縮進不會包含在字符串中。 """ 的結束符號決定了縮進:字面量中

的任何⼀個⾮空⾏必須起始於多⾏字符串字⾯量結束符號的前面;空格和製表符不會被轉換。你可以包在縮進後含額外的空格和制

表符;這些空格和製表符會在字符串中出現。

多⾏字符串字⾯量中的一⾏結束使⽤規範化的換⾏符號。儘管你的源代碼混⽤了回車和換⾏符,字符串中所有的⾏結束都必須⼀

樣.

在多⾏字符串字⾯量里, 在⾏末用反斜線( \ )可以省略字符串行間中斷。 反斜線之間的空⽩和⾏間中斷也可以省略。 你可以在你

的代碼⾥⽤這種語法硬包裹多⾏字符串字⾯量,不需要改變產⽣的字符串的值。

可以在字符串字⾯量中使用的轉義特殊符號如下:

空字符  \0

反斜線  \\

⽔水平製表符  \t

換⾏行行符  \n

回⻋車符  \r

雙引號  \"

單引號  \'

Unicode 標量 \u{ n } ,n 爲一到八位的十六進制數字

字符串字⾯量允許在反斜槓( \ )後的括號 () 中插入表達式的值。插入表達式可以包含字符串字⾯量,但不能包含未轉義的反斜線

( \ )、回⻋符以及換⾏符。

例如,以下所有字符串字⾯量的值都是相同的:

"1 2 3"

"1 2 \("3")"

"1 2 \(3)"

"1 2 \(1 + 2)"

let x = 3; "1 2 \(x)"

可以使用一對或多對擴展分隔符(#)包裹字符串進⾏分隔,被分隔的字符串的形式如下所示:

#" characters "#

#"""

characters

"""#

特殊字符在被分隔符分隔的結果字符串中會展示爲普通字符,⽽不是特殊字符。你可以使用擴展分隔符來創建一些具有特殊效果

的字符串。例如,⽣成字符串插值,啓動或終⽌轉義序列(字符串)。

以下所示,由字符串字⾯量和擴展分隔符所創建的字符串是等價的:

let string = #"\(x) \ " \u{2603}"#

let escaped = "\\(x) \\ \" \\u{2603}"

print(string)

// Prints "\(x) \ " \u{2603}"

print(string == escaped)

// Prints "true"

如果在一個字符串中使用多對擴展分隔符,請不要在分隔符之間使用空格。

print(###"Line 1\###nLine 2"###) // OK

print(# # #"Line 1\# # #nLine 2"# # #) // Error

使用擴展分隔符創建的多⾏字符串字⾯量與普通多⾏字符串字⾯量具有相同的縮進要求。 字符串字⾯量的默認推導類型爲 String 。

用 + 操作符連接的字符型字⾯量是在編譯時進⾏連接的。⽐如下面的 textA 和 textB 是完全一樣的, textA沒有任何運⾏時的連

接操作。

let textA = "Hello " + "world"

let textB = "Hello world"

 

運算符

Swift 標準庫定義了許多可供使用的運算符,其中大部分在《基礎運算符》和《高級運算符》中進⾏了闡述。這一小節將描述哪

些字符能用於⾃定義運算符。

自定義運算符可以由以下其中之一的 ASCII 字符

/、=、-、+、!、*、%、<、>、&、|、^、? 以及 ~,或者後⾯語法中規定的任一個 Unicode 字符(其中包含了數學運算符、零散符

號(Miscellaneous Symbols) 以及印刷符號(Dingbats)之類的 Unicode 塊)開始。在第一個字符之後,允許使用組合型 Unicode 字

符。

您也可以以點號( . )開頭來定義自定義運算符。這些運算符可以包含額外的點,例如 .+. 。如果某個運算符不是以點號開頭的,那

麼它就無法再包含另外的點號了。例如, +.+ 就會被看作爲一個 + 運算符後⾯跟着一個 .+ 運算符。

雖然您可以用問號 ? 來自定義運算符,但是這個運算符不能只包含單獨的一個問號。此外,雖然運算符可以包含一個驚歎號 ! ,

但是前綴運算符不能夠以問號或者驚歎號開頭。

注意

以下這些標記 =、->、//、/*、*/、.、<(前綴運算符)、&、?、?(中綴運算符)、>(後綴運算符)、 ! 、 ? 是被系統保留的。這些符號

不能被重載,也不能用於自定義運算符。

運算符兩側的空白被用來區分該運算符是否爲前綴運算符、後綴運算符或二元運算符。規則總結如下:

如果運算符兩側都有空白或兩側都無空白,將被看作二元運算符。例如: a+++b 和 a +++ b 當中的 +++ 運算符會被看作二元運算

符。

如果運算符只有左側空白,將被看作一元前綴運算符。例如 a +++b 中的 +++ 運算符會被看做是一元前綴運算符。

如果運算符只有右側空白,將被看作一元后綴運算符。例如 a+++ b 中的 +++ 運算符會被看作是一元后綴運算符。

如果運算符左側沒有空白並緊跟 . ,將被看作一元后綴運算符。例如 a+++.b 中的 +++ 運算符會被視爲一元后綴運算符(即上式被

視爲 a+++ .b ⽽不是 a +++ .b )。

鑑於這些規則,運算符前的字符 (、[ 和 {,運算符後的字符 )、] 和 },以及字符 ,、; 和 : 都被視爲空白。

以上規則需注意一點,如果預定義運算符 ! 或 ? 左側沒有空白,則不管右側是否有空白都將被看作後綴運算符。如果將 ? 用作可

選鏈式調用運算符,左側必須無空白。如果用於條件運算符 ? : ,必須兩側都有空白。

在某些特定的設計中 ,以 < 或 > 開頭的運算符會被分離成兩個或多個符號,剩餘部分可能會以同樣的方式被再次分離。因此,

在 Dictionary<String, Array<Int>> 中沒有必要添加空白來消除閉合字符 > 的歧義。在這個例子中, 閉合字符 > 不會被視爲單獨

的符號,因⽽不會被錯誤解析爲 >> 運算符。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章