2.0 翻譯+校對:buginux
2.1 翻譯:mmoaay
2.2 翻譯+校對:星夜暮晨,2016-04-06
本頁包含內(nèi)容:
Swift 的“詞法結(jié)構(gòu) (lexical structure)” 描述了能構(gòu)成該語言中合法符號 (token) 的字符序列。這些合法符號組成了語言中最底層的構(gòu)建基塊,并在之后的章節(jié)中用于描述語言的其他部分。一個合法符號由一個標(biāo)識符 (identifier)、關(guān)鍵字 (keyword)、標(biāo)點(diǎn)符號 (punctuation)、字面量 (literal) 或運(yùn)算符 (operator) 組成。
通常情況下,通過考慮輸入文本當(dāng)中可能的最長子串,并且在隨后將介紹的語法約束之下,根據(jù)隨后將介紹的語法約束生成的,根據(jù) Swift 源文件當(dāng)中的字符來生成相應(yīng)的“符號”。這種方法稱為“最長匹配 (longest match)”,或者“最大適合(maximal munch)”。
空白 (whitespace) 有兩個用途:分隔源文件中的符號以及幫助區(qū)分運(yùn)算符屬于前綴還是后綴(參見 運(yùn)算符),在其他情況下空白則會被忽略。以下的字符會被當(dāng)作空白:空格(U+0020)、換行符(U+000A)、回車符(U+000D)、水平制表符(U+0009)、垂直制表符(U+000B)、換頁符(U+000C)以及空字符(U+0000)。
注釋被編譯器當(dāng)作空白處理。單行注釋由 //
開始直至遇到換行符(U+000A)或者回車符(U+000D)。多行注釋由 /*
開始,以 */
結(jié)束。注釋允許嵌套,但注釋標(biāo)記必須匹配。
正如 Markup Formatting Reference 所述,注釋可以包含附加的格式和標(biāo)記。
標(biāo)識符(identifier) 可以由以下的字符開始:大寫或小寫的字母 A
到 Z
、下劃線 (_
)、基本多文種平面 (Basic Multilingual Plane) 中非字符數(shù)字組合的 Unicode 字符以及基本多文種平面以外的非個人專用區(qū)字符。在首字符之后,允許使用數(shù)字和組合 Unicode 字符。
使用保留字作為標(biāo)識符,需要在其前后增加反引號 (`
)。例如,class
不是合法的標(biāo)識符,但可以使用 `class`
。反引號不屬于標(biāo)識符的一部分,`x`
和 x
表示同一標(biāo)識符。
閉包中如果沒有明確指定參數(shù)名稱,參數(shù)將被隱式命名為 $0
、$1
、$2
等等。這些命名在閉包作用域范圍內(nèi)是合法的標(biāo)識符。
標(biāo)識符語法
標(biāo)識符 → 頭部標(biāo)識符 標(biāo)識符字符組可選
標(biāo)識符 → `頭部標(biāo)識符 標(biāo)識符字符組可選`
標(biāo)識符 → 隱式參數(shù)名
標(biāo)識符列表 → 標(biāo)識符 | 標(biāo)識符 , 標(biāo)識符列表
頭部標(biāo)識符 → 大寫或小寫字母 A - Z
頭部標(biāo)識符 → _
頭部標(biāo)識符 → U+00A8,U+00AA,U+00AD,U+00AF,U+00B2–U+00B5,或者 U+00B7–U+00BA
頭部標(biāo)識符 → U+00BC–U+00BE,U+00C0–U+00D6,U+00D8–U+00F6,或者 U+00F8–U+00FF
頭部標(biāo)識符 → U+0100–U+02FF,U+0370–U+167F,U+1681–U+180D,或者 U+180F–U+1DBF
頭部標(biāo)識符 → U+1E00–U+1FFF
頭部標(biāo)識符 → U+200B–U+200D,U+202A–U+202E,U+203F–U+2040,U+2054,或者 U+2060–U+206F
頭部標(biāo)識符 → U+2070–U+20CF,U+2100–U+218F,U+2460–U+24FF,或者 U+2776–U+2793
頭部標(biāo)識符 → U+2C00–U+2DFF 或者 U+2E80–U+2FFF
頭部標(biāo)識符 → U+3004–U+3007,U+3021–U+302F,U+3031–U+303F,或者 U+3040–U+D7FF
頭部標(biāo)識符 → U+F900–U+FD3D,U+FD40–U+FDCF,U+FDF0–U+FE1F,或者 U+FE30–U+FE44
頭部標(biāo)識符 → U+FE47–U+FFFD
頭部標(biāo)識符 → U+10000–U+1FFFD,U+20000–U+2FFFD,U+30000–U+3FFFD,或者 U+40000–U+4FFFD
頭部標(biāo)識符 → U+50000–U+5FFFD,U+60000–U+6FFFD,U+70000–U+7FFFD,或者 U+80000–U+8FFFD
頭部標(biāo)識符 → U+90000–U+9FFFD,U+A0000–U+AFFFD,U+B0000–U+BFFFD,或者 U+C0000–U+CFFFD
頭部標(biāo)識符 → U+D0000–U+DFFFD 或者 U+E0000–U+EFFFD
標(biāo)識符字符 → 數(shù)值 0 - 9
標(biāo)識符字符 → U+0300–U+036F,U+1DC0–U+1DFF,U+20D0–U+20FF,或者 U+FE20–U+FE2F
標(biāo)識符字符 → 頭部標(biāo)識符
標(biāo)識符字符組 → 標(biāo)識符字符 標(biāo)識符字符組可選
隱式參數(shù)名 → $ 十進(jìn)制數(shù)字列表
下面這些被保留的關(guān)鍵字不允許用作標(biāo)識符,除非使用反引號轉(zhuǎn)義,具體描述請參考 標(biāo)識符。除了 inout
、var
以及 let
之外的關(guān)鍵字可以用作某個函數(shù)聲明或者函數(shù)調(diào)用當(dāng)中的外部參數(shù)名,不用添加反引號轉(zhuǎn)義。
associatedtype
、class
、deinit
、enum
、extension
、func
、import
、init
、inout
、internal
、let
、operator
、private
、protocol
、public
、static
、struct
、subscript
、typealias
以及 var
。break
、case
、continue
、default
、defer
、do
、else
、fallthrough
、for
、guard
、if
、in
、repeat
、return
、switch
、where
以及 while
。as
、catch
、dynamicType
、false
、is
、nil
、rethrows
、super
、self
、Self
、throw
、throws
、true
、try
、#column
、#file
、#function
以及 #line
。_
。#
) 開頭的關(guān)鍵字:#available
、#column
、#else#elseif
、#endif
、#file
、#function
、#if
、#line
以及 #selector
。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
。這些關(guān)鍵字在特定上下文之外可以被用做標(biāo)識符。以下符號被當(dāng)作保留符號,不能用于自定義運(yùn)算符: (
、)
、{
、}
、[
、]
、.
、,
、:
、;
、=
、@
、#
、&
(作為前綴運(yùn)算符)、->
、`
、?
、!
(作為后綴運(yùn)算符)。
字面量 (literal) 用來表示源碼中某種特定類型的值,比如一個數(shù)字或字符串。
下面是字面量的一些示例:
42 // 整數(shù)字面量
3.14159 // 浮點(diǎn)數(shù)字面量
"Hello, world!" // 字符串字面量
true // 布爾值字面量
字面量本身并不包含類型信息。事實(shí)上,一個字面量會被解析為擁有無限的精度,然后 Swift 的類型推導(dǎo)會嘗試去推導(dǎo)出這個字面量的類型。比如,在 let x: Int8 = 42
這個聲明中,Swift 使用了顯式類型標(biāo)注(: Int8
)來推導(dǎo)出 42
這個整數(shù)字面量的類型是 Int8
。如果沒有可用的類型信息, Swift 則會從標(biāo)準(zhǔn)庫中定義的字面量類型中推導(dǎo)出一個默認(rèn)的類型。整數(shù)字面量的默認(rèn)類型是 Int
,浮點(diǎn)數(shù)字面量的默認(rèn)類型是 Double
,字符串字面量的默認(rèn)類型是 String
,布爾值字面量的默認(rèn)類型是 Bool
。比如,在 let str = "Hello, world"
這個聲明中,字符串 "Hello, world"
的默認(rèn)推導(dǎo)類型就是 String
。
當(dāng)為一個字面量值指定了類型標(biāo)注的時候,這個標(biāo)注的類型必須能通過這個字面量值實(shí)例化。也就是說,這個類型必須符合這些 Swift 標(biāo)準(zhǔn)庫協(xié)議中的一個:整數(shù)字面量的 IntegerLiteralConvertible
協(xié)議、浮點(diǎn)數(shù)字面量的 FloatingPointLiteralConvertible
協(xié)議、字符串字面量的 StringLiteralConvertible
協(xié)議以及布爾值字面量的 BooleanLiteralConvertible
協(xié)議。比如,Int8
符合 IntegerLiteralConvertible
協(xié)議,因此它能在 let x: Int8 = 42
這個聲明中作為整數(shù)字面量 42
的類型標(biāo)注。
字面量語法
字面量 → 數(shù)值字面量 | 字符串字面量 | 布爾值字面量 | nil 字面量
數(shù)值字面量 → -可選 整數(shù)字面量 | -可選 浮點(diǎn)數(shù)字面量
</a> 布爾值字面量 → true | false
nil 字面量 → nil
整數(shù)字面量 (Integer Literals) 表示未指定精度整數(shù)的值。整數(shù)字面量默認(rèn)用十進(jìn)制表示,可以加前綴來指定其他的進(jìn)制。二進(jìn)制字面量加 0b
,八進(jìn)制字面量加 0o
,十六進(jìn)制字面量加 0x
。
十進(jìn)制字面量包含數(shù)字 0
至 9
。二進(jìn)制字面量只包含 0
或 1
,八進(jìn)制字面量包含數(shù)字 0
至 7
,十六進(jìn)制字面量包含數(shù)字 0
至 9
以及字母 A
至 F
(大小寫均可)。
負(fù)整數(shù)的字面量在整數(shù)字面量前加負(fù)號 -
,比如 -42
。
整型字面面可以使用下劃線 (_
) 來增加數(shù)字的可讀性,下劃線會被系統(tǒng)忽略,因此不會影響字面量的值。同樣地,也可以在數(shù)字前加 0
,這同樣也會被系統(tǒng)所忽略,并不會影響字面量的值。
除非特別指定,整數(shù)字面量的默認(rèn)推導(dǎo)類型為 Swift 標(biāo)準(zhǔn)庫類型中的 Int
。Swift 標(biāo)準(zhǔn)庫還定義了其他不同長度以及是否帶符號的整數(shù)類型,請參考 整數(shù)。
整數(shù)字面量語法
整數(shù)字面量 → 二進(jìn)制字面量
整數(shù)字面量 → 八進(jìn)制字面量
整數(shù)字面量 → 十進(jìn)制字面量
整數(shù)字面量 → 十六進(jìn)制字面量
二進(jìn)制字面量 → 0b 二進(jìn)制數(shù)字 二進(jìn)制字面量字符組可選 </a>
二進(jìn)制數(shù)字 → 數(shù)值 0 到 1
二進(jìn)制字面量字符 → 二進(jìn)制數(shù)字 | _
二進(jìn)制字面量字符組 → 二進(jìn)制字面量字符 二進(jìn)制字面量字符組可選
八進(jìn)制字面量 → 0o 八進(jìn)字?jǐn)?shù)字 八進(jìn)制字符組可選
</a>
八進(jìn)字?jǐn)?shù)字 → 數(shù)值 0 到 7
八進(jìn)制字符 → 八進(jìn)字?jǐn)?shù)字 | _
八進(jìn)制字符組 → 八進(jìn)制字符 八進(jìn)制字符組可選
十進(jìn)制字面量 → 十進(jìn)制數(shù)字 十進(jìn)制字符組可選
</a> 十進(jìn)制數(shù)字 → 數(shù)值 0 到 9
十進(jìn)制數(shù)字組 → 十進(jìn)制數(shù)字 十進(jìn)制數(shù)字組可選
</a> 十進(jìn)制字符 → 十進(jìn)制數(shù)字 | _
十進(jìn)制字符組 → 十進(jìn)制字符 十進(jìn)制字符組可選
十六進(jìn)制字面量 → 0x 十六進(jìn)制數(shù)字 十六進(jìn)制字面量字符組可選
</a> 十六進(jìn)制數(shù)字 → 數(shù)值 0 到 9, 字母 a 到 f, 或 A 到 F
十六進(jìn)制字符 → 十六進(jìn)制數(shù)字 | _
十六進(jìn)制字面量字符組 → 十六進(jìn)制字符 十六進(jìn)制字面量字符組可選
浮點(diǎn)數(shù)字面量 (Floating-point literals) 表示未指定精度浮點(diǎn)數(shù)的值。
浮點(diǎn)數(shù)字面量默認(rèn)用十進(jìn)制表示(無前綴),也可以用十六進(jìn)制表示(加前綴 0x
)。
十進(jìn)制浮點(diǎn)數(shù)字面量由十進(jìn)制數(shù)字串后跟小數(shù)部分或指數(shù)部分(或兩者皆有)組成。十進(jìn)制小數(shù)部分由小數(shù)點(diǎn) (.
) 后跟十進(jìn)制數(shù)字串組成。指數(shù)部分由大寫或小寫字母 e
為前綴后跟十進(jìn)制數(shù)字串組成,這串?dāng)?shù)字表示 e
之前的數(shù)量乘以 10 的幾次方。例如:1.25e2
表示 1.25 x 102,也就是 125.0
;同樣,1.25e-2
表示 1.25 x 10ˉ2,也就是 0.0125
。
十六進(jìn)制浮點(diǎn)數(shù)字面量由前綴 0x
后跟可選的十六進(jìn)制小數(shù)部分以及十六進(jìn)制指數(shù)部分組成。十六進(jìn)制小數(shù)部分由小數(shù)點(diǎn)后跟十六進(jìn)制數(shù)字串組成。指數(shù)部分由大寫或小寫字母 p
為前綴后跟十進(jìn)制數(shù)字串組成,這串?dāng)?shù)字表示 p
之前的數(shù)量乘以 2 的幾次方。例如:0xFp2
表示 15 x 22,也就是 60
;同樣,0xFp-2
表示 15 x 2ˉ2,也就是 3.75
。
負(fù)數(shù)的浮點(diǎn)數(shù)字面量由負(fù)號 (-
) 和浮點(diǎn)數(shù)字面量組成,例如 -42.5
。
浮點(diǎn)數(shù)字面量允許使用下劃線 (_
) 來增強(qiáng)數(shù)字的可讀性,下劃線會被系統(tǒng)忽略,因此不會影響字面量的值。同樣地,也可以在數(shù)字前加 0
,并不會影響字面量的值。
除非特別指定,浮點(diǎn)數(shù)字面量的默認(rèn)推導(dǎo)類型為 Swift 標(biāo)準(zhǔn)庫類型中的 Double
,表示 64 位浮點(diǎn)數(shù)。Swift 標(biāo)準(zhǔn)庫也定義了 Float
類型,表示 32 位浮點(diǎn)數(shù)。
浮點(diǎn)數(shù)字面量語法
浮點(diǎn)數(shù)字面量 → 十進(jìn)制字面量 十進(jìn)制分?jǐn)?shù)可選 十進(jìn)制指數(shù)可選
浮點(diǎn)數(shù)字面量 → 十六進(jìn)制字面量 十六進(jìn)制分?jǐn)?shù)可選 十六進(jìn)制指數(shù)
十進(jìn)制分?jǐn)?shù) → . 十進(jìn)制字面量
十進(jìn)制指數(shù) → 十進(jìn)制指數(shù) e 正負(fù)號可選 十進(jìn)制字面量
十六進(jìn)制分?jǐn)?shù) → . 十六進(jìn)制數(shù)字 十六進(jìn)制字面量字符組可選
十六進(jìn)制指數(shù) → 十六進(jìn)制指數(shù) p 正負(fù)號可選 十進(jìn)制字面量
十進(jìn)制指數(shù) e → e | E
</a> 十六進(jìn)制指數(shù) p → p | P
正負(fù)號 → + | -
字符串字面量由被包在雙引號中的一串字符組成,形式如下:
"
字符
"
字符串字面量中不能包含未轉(zhuǎn)義的雙引號("
)、未轉(zhuǎn)義的反斜線(\
)、回車符、換行符。
可以在字符串字面量中使用的轉(zhuǎn)義特殊符號如下:
\0
\\
\t
\n
\r
\"
\'
\u{
n}
,n 為一到八位的十六進(jìn)制數(shù)字字符串字面量允許在反斜杠 (\
) 后的括號 ()
中插入表達(dá)式的值。插入表達(dá)式可以包含字符串字面量,但不能包含未轉(zhuǎn)義的雙引號 ("
)、未轉(zhuǎn)義的反斜線 (\
)、回車符以及換行符。
例如,以下所有字符串字面量的值都是相同的:
"1 2 3"
"1 2 \("3")"
"1 2 \(3)"
"1 2 \(1 + 2)"
let x = 3; "1 2 \(x)"
字符串字面量的默認(rèn)推導(dǎo)類型為 String
。更多有關(guān) String
類型的信息請參考 字符串和字符 以及 String Structure Reference。
用 +
操作符連接的字符型字面量是在編譯時進(jìn)行連接的。比如下面的 textA
和 textB
是完全一樣的,textA
沒有任何運(yùn)行時的連接操作。
let textA = "Hello " + "world"
let textB = "Hello world"
字符串字面量語法
字符串字面量 → 靜態(tài)字符串字面量 | 插值字符串字面量
靜態(tài)字符串字面量 → "引用文本可選"
</a> 引用文本 → 引用文本項 引用文本可選
引用文本項 → 轉(zhuǎn)義字符
引用文本項 → 除了 "、\、U+000A、U+000D 以外的所有 Unicode 字符
插值字符串字面量 → "插值文本可選"
</a> 插值文本 → 插值文本項 插值文本可選
插值文本項 → \**(表達(dá)式)* | [引用文本項*](#quoted-text-item)
轉(zhuǎn)義字符 → \**0 | \**\ | \t | \n | \r | \" | \'
轉(zhuǎn)義字符 → \u { unicode 標(biāo)量數(shù)字 }
unicode 標(biāo)量數(shù)字 → 一到八位的十六進(jìn)制數(shù)字
Swift 標(biāo)準(zhǔn)庫定義了許多可供使用的運(yùn)算符,其中大部分在 基礎(chǔ)運(yùn)算符 和 高級運(yùn)算符 中進(jìn)行了闡述。這一小節(jié)將描述哪些字符能用于自定義運(yùn)算符。
自定義運(yùn)算符可以由以下其中之一的 ASCII 字符 /
、=
、 -
、+
、!
、*
、%
、<
、>
、&
、|
、^
、?
以及 ~
,或者后面語法中規(guī)定的任一個 Unicode 字符(其中包含了數(shù)學(xué)運(yùn)算符、零散符號(Miscellaneous Symbols) 以及印刷符號 (Dingbats) 之類的 Unicode 塊)開始。在第一個字符之后,允許使用組合型 Unicode 字符。
您也可以以點(diǎn)號 (.
) 開頭來定義自定義運(yùn)算符。這些運(yùn)算符可以包含額外的點(diǎn),例如 .+.
。如果某個運(yùn)算符不是以點(diǎn)號開頭的,那么它就無法再包含另外的點(diǎn)號了。例如,+.+
就會被看作為一個 +
運(yùn)算符后面跟著一個 .+
運(yùn)算符。
雖然您可以用問號 ?
來自定義運(yùn)算符,但是這個運(yùn)算符不能只包含單獨(dú)的一個問號。此外,雖然運(yùn)算符可以包含一個驚嘆號 !
,但是前綴運(yùn)算符不能夠以問號或者驚嘆號開頭。
注意
以下這些標(biāo)記=
、->
、//
、/*
、*/
、.
、<
(前綴運(yùn)算符)、&
、?
、?
(中綴運(yùn)算符)、>
(后綴運(yùn)算符)、!
、?
是被系統(tǒng)保留的。這些符號不能被重載,也不能用于自定義運(yùn)算符。
運(yùn)算符兩側(cè)的空白被用來區(qū)分該運(yùn)算符是否為前綴運(yùn)算符、后綴運(yùn)算符或二元運(yùn)算符。規(guī)則總結(jié)如下:
a+++b
和 a +++ b
當(dāng)中的 +++
運(yùn)算符會被看作二元運(yùn)算符。a +++b
中的 +++
運(yùn)算符會被看做是一元前綴運(yùn)算符。 a+++ b
中的 +++
運(yùn)算符會被看作是一元后綴運(yùn)算符。.
,將被看作一元后綴運(yùn)算符。例如 a+++.b
中的 +++
運(yùn)算符會被視為一元后綴運(yùn)算符(即上式被視為 a+++ .b
而不是 a +++ .b
)。鑒于這些規(guī)則,運(yùn)算符前的字符 (
、[
和 {
,運(yùn)算符后的字符 )
、]
和 }
,以及字符 ,
、;
和 :
都被視為空白。
以上規(guī)則需注意一點(diǎn),如果預(yù)定義運(yùn)算符 !
或 ?
左側(cè)沒有空白,則不管右側(cè)是否有空白都將被看作后綴運(yùn)算符。如果將 ?
用作可選鏈?zhǔn)秸{(diào)用運(yùn)算符,左側(cè)必須無空白。如果用于條件運(yùn)算符 ? :
,必須兩側(cè)都有空白。
在某些特定的設(shè)計中 ,以 <
或 >
開頭的運(yùn)算符會被分離成兩個或多個符號,剩余部分可能會以同樣的方式被再次分離。因此,在 Dictionary<String, Array<Int>>
中沒有必要添加空白來消除閉合字符 >
的歧義。在這個例子中, 閉合字符 >
不會被視為單獨(dú)的符號,因而不會被錯誤解析為 >>
運(yùn)算符。
要學(xué)習(xí)如何自定義運(yùn)算符,請參考 自定義運(yùn)算符 和 運(yùn)算符聲明。要學(xué)習(xí)如何重載運(yùn)算符,請參考 運(yùn)算符函數(shù)。
運(yùn)算符語法
運(yùn)算符 → 頭部運(yùn)算符 運(yùn)算符字符組可選
運(yùn)算符 → 頭部點(diǎn)運(yùn)算符 點(diǎn)運(yùn)算符字符組可選
頭部運(yùn)算符 → / | = | - | + | ! | * | % | < | > | & | | | ^ | ~ | ?
頭部運(yùn)算符 → U+00A1–U+00A7
頭部運(yùn)算符 → U+00A9 或 U+00AB
頭部運(yùn)算符 → U+00AC 或 U+00AE
頭部運(yùn)算符 → U+00B0–U+00B1,U+00B6,U+00BB,U+00BF,U+00D7,或 U+00F7
頭部運(yùn)算符 → U+2016–U+2017 或 U+2020–U+2027
頭部運(yùn)算符 → U+2030–U+203E
頭部運(yùn)算符 → U+2041–U+2053
頭部運(yùn)算符 → U+2055–U+205E
頭部運(yùn)算符 → U+2190–U+23FF
頭部運(yùn)算符 → U+2500–U+2775
頭部運(yùn)算符 → U+2794–U+2BFF
頭部運(yùn)算符 → U+2E00–U+2E7F
頭部運(yùn)算符 → U+3001–U+3003
頭部運(yùn)算符 → U+3008–U+3030
運(yùn)算符字符 → 頭部運(yùn)算符
運(yùn)算符字符 → U+0300–U+036F
運(yùn)算符字符 → U+1DC0–U+1DFF
運(yùn)算符字符 → U+20D0–U+20FF
運(yùn)算符字符 → U+FE00–U+FE0F
運(yùn)算符字符 → U+FE20–U+FE2F
運(yùn)算符字符 → U+E0100–U+E01EF
運(yùn)算符字符組 → 運(yùn)算符字符 運(yùn)算符字符組可選
頭部點(diǎn)運(yùn)算符 → ..
</a> 點(diǎn)運(yùn)算符字符 → . | 運(yùn)算符字符
點(diǎn)運(yùn)算符字符組 → 點(diǎn)運(yùn)算符字符 點(diǎn)運(yùn)算符字符組可選
二元運(yùn)算符 → 運(yùn)算符
</a> 前綴運(yùn)算符 → 運(yùn)算符
后綴運(yùn)算符 → 運(yùn)算符