做者:Jordan Morgan,原文連接,原文日期:2017-02-11 譯者:鄭一一;校對:numbbbbb,pmst;定稿:Pancfhtml
有句話以前我提過,今天還想再說一次。那就是打鐵還需自身硬。對於自身能力的嚴格要求,能夠幫助實現咱們全部求之不得的東西。git
提及來可能有些消極,知識畢竟是永遠學不完的。不論如何,今天 咱們先來學習一下 Swift 中的每個關鍵字(V3.0.1),在介紹每一個關鍵字的時候,同時會附帶一段代碼加以說明。github
在這些關鍵字之中,會有你熟悉或者不熟悉的部分。但爲了最好的閱讀和學習體驗,我把它們所有列出來了。文章篇幅有些長,你準備好了麼?數據庫
讓咱們如今就開始吧。express
associatedtype:在協議中,定義一個類型的佔位符名稱。直到協議被實現,該佔位符纔會被指定具體的類型。swift
protocol Entertainment
{
associatedtype MediaType
}
class Foo : Entertainment
{
typealias MediaType = String //能夠指定任意類型
}
複製代碼
class:通用、靈活的結構體,是程序的基礎組成部分。與 struct 相似,不一樣之處在於:數組
容許一個類繼承另外一個類的特性。安全
類型轉換,容許在運行時檢查和指定一個類的實際類型。app
析構方法容許類的實例釋放全部資源。框架
引用計數容許多個引用指向一個實例。
class Person
{
var name:String
var age:Int
var gender:String
}
deinit:當一個類的實例即將被銷燬時,會調用這個方法。
class Person
{
var name:String
var age:Int
var gender:String
deinit
{
//從堆中釋放,並釋放的資源
}
}
複製代碼
enum:定義了包含一組有關聯的值的類型,並能夠以一種類型安全的方式使用這些值。在 Swift 中,枚舉是一等類型,擁有在其它語言中只有 class 纔會支持的特性。
enum Gender
{
case male
case female
}
複製代碼
extension:容許給已有的類、結構體、枚舉、協議類型,添加新功能。
class Person
{
var name:String = ""
var age:Int = 0
var gender:String = ""
}
extension Person
{
func printInfo()
{
print("My name is \(name), I'm \(age) years old and I'm a \(gender).")
}
}
複製代碼
fileprivate:訪問控制權限,只容許在定義源文件中訪問。
class Person
{
fileprivate var jobTitle:String = ""
}
extension Person
{
//當 extension 和 class 在同一個文件中時,容許訪問
func printJobTitle()
{
print("My job is (jobTitle)")
}
}
複製代碼
func:包含用於執行特定任務的代碼塊。
func addNumbers(num1:Int, num2:Int) -> Int
{
return num1+num2
}
複製代碼
import:引入一個以獨立單元構建的框架或者應用。
import UIKit
//可使用 UIKit 框架下的全部代碼
class Foo {}
複製代碼
init:類、結構體、枚舉的實例的初始化準備過程。
class Person
{
init()
{
//設置默認值,實例準備被使用
}
}
複製代碼
inout:將一個值傳入函數,並能夠被函數修改,而後將值傳回到調用處,來替換初始值。適用於引用類型和值類型。
func dangerousOp(_ error:inout NSError?)
{
error = NSError(domain: "", code: 0, userInfo: ["":""])
}
var potentialError:NSError?
dangerousOp(&potentialError)
//代碼運行到這裏,potentialError 再也不是 nil,而是已經被初始化
複製代碼
internal:訪問控制權限,容許同一個模塊下的全部源文件訪問,若是在不一樣模塊下則不容許訪問。
class Person
{
internal var jobTitle:String = ""
}
let aPerson = Person()
aPerson.jobTitle = "This can set anywhere in the application"
複製代碼
let:定義一個不可變的變量。
let constantString = "This cannot be mutated going forward"
複製代碼
open:訪問控制權限,容許在定義的模塊外也能夠訪問源文件裏的全部類,並進行子類化。對於類成員,容許在定義的模塊以外訪問和重寫。
open var foo:String? //這個屬性容許在 app 內或 app 外重寫和訪問。在開發框架的時候,會應用到這個訪問修飾符。
複製代碼
operator:特殊符號,用於檢查、修改、組合值。
//一元運算符 "-",改變值的符號
let foo = 5
let anotherFoo = -foo //anotherFoo 等於 -5
//二元運算符 "+" 將兩個值相加
let box = 5 + 3
//邏輯運算符 "&&" 將兩個布爾值進行組合運算
if didPassCheckOne && didPassCheckTwo
//三元運算符須要使用三個值
let isLegalDrinkingAgeInUS:Bool = age >= 21 ? true : false
複製代碼
private:訪問控制權限,只容許實體在定義的類以及相同源文件內的 extension 中訪問。
class Person
{
private var jobTitle:String = ""
}
// 當 extension 和 class 不在同一個源文件時
extension Person
{
// 沒法編譯經過,只有在同一個源文件下才能夠訪問
func printJobTitle()
{
print("My job is (jobTitle)")
}
}
複製代碼
protocol:定義了一組方法、屬性或其它要求,用於知足特定任務和一系列功能。
protocol Blog
{
var wordCount:Int { get set }
func printReaderStats()
}
class TTIDGPost : Blog
{
var wordCount:Int
init(wordCount:Int)
{
self.wordCount = wordCount
}
func printReaderStats()
{
//打印 post 的數據
}
}
複製代碼
public:訪問控制權限,容許在定義的模塊外也能夠訪問源文件裏的全部類,但只有在同一個模塊內能夠進行子類化。對於類成員,容許在同個模塊下訪問和重寫。
public var foo:String? //只容許在 app 內重寫和訪問。
複製代碼
static:用於定義類方法,在類型自己進行調用。此外還能夠定義靜態成員。
class Person
{
var jobTitle:String?
static func assignRandomName(_ aPerson:Person)
{
aPerson.jobTitle = "Some random job"
}
}
let somePerson = Person()
Person.assignRandomName(somePerson)
//somePerson.jobTitle 的值是 "Some random job"
複製代碼
struct:通用、靈活的結構體,是程序的基礎組成部分,並提供了默認初始化方法。與 class 不一樣,當 struct 在代碼中被傳遞時,是被拷貝的,並不使用引用計數。除此以外,struct 沒有下面的這些功能:
使用繼承。
運行時的類型轉換。
使用析構方法。
struct Person
{
var name:String
var age:Int
var gender:String
}
subscript:訪問集合、列表、序列中成員元素的快捷方式。
var postMetrics = ["Likes":422, "ReadPercentage":0.58, "Views":3409]
let postLikes = postMetrics["Likes"]
複製代碼
typealias:給代碼中已經存在的類,取別名。
typealias JSONDictionary = [String: AnyObject]
func parseJSON(_ deserializedData:JSONDictionary){}
複製代碼
var:定義可變變量。
var mutableString = ""
mutableString = "Mutated"
複製代碼
break:終止程序中循環的執行,好比 if 語句、switch 語句。
for idx in 0...3
{
if idx % 2 == 0
{
//當 idx 等於偶數時,退出 for 循環
break
}
}
複製代碼
case:該語句在 switch 語句中列出,在每一個分支能夠進行模式匹配。
let box = 1
switch box
{
case 0:
print("Box equals 0")
case 1:
print("Box equals 1")
default:
print("Box doesn't equal 0 or 1")
}
複製代碼
continue:用於終止循環的當前迭代,並進入下一次迭代,而不會中止整個循環的執行。
for idx in 0...3
{
if idx % 2 == 0
{
//直接開始循環的下一次迭代
continue
}
print("This code never fires on even numbers")
}
複製代碼
default:用於涵蓋在 switch 語句中,全部未明確列出的枚舉成員。
let box = 1
switch box
{
case 0:
print("Box equals 0")
case 1:
print("Box equals 1")
default:
print("Covers any scenario that doesn't get addressed above.")
}
複製代碼
defer:用於在程序離開當前做用域以前,執行一段代碼。
func cleanUpIO()
{
defer
{
print("This is called right before exiting scope")
}
//關閉文件流等。
}
複製代碼
do:用於表示處理錯誤代碼段的開始。
do
{
try expression
//語句
}
catch someError ex
{
//處理錯誤
}
複製代碼
else:與 if 語句結合使用。當條件爲 true,執行一段代碼。當條件爲 false,執行另外一段代碼。
if val > 1
{
print("val is greater than 1")
}
else
{
print("val is not greater than 1")
}
複製代碼
fallthrough:顯式地容許從當前 case 跳轉到下一個相鄰 case 繼續執行代碼。
let box = 1
switch box
{
case 0:
print("Box equals 0")
fallthrough
case 1:
print("Box equals 0 or 1")
default:
print("Box doesn't equal 0 or 1")
}
複製代碼
for:在序列上迭代,好比一組特定範圍內的數字,數組中的元素,字符串中的字符。*與關鍵字 in 成對使用。
for _ in 0..<3 { print ("This prints 3 times") }
複製代碼
guard:當有一個以上的條件不知足要求時,將離開當前做用域。同時還提供解包可選類型的功能。
private func printRecordFromLastName(userLastName: String?)
{
guard let name = userLastName, name != "Null" else
{
//userLastName = "Null",須要提早退出
return
}
//繼續執行代碼
print(dataStore.findByLastName(name))
}
複製代碼
if:當條件知足時,執行代碼。
if 1 > 2
{
print("This will never execute")
}
複製代碼
in:在序列上迭代,好比一組特定範圍內的數字,數組中的元素,字符串中的字符。*與關鍵字 key 搭配使用。
for _ in 0..<3 { print ("This prints 3 times") }
複製代碼
repeat:在使用循環的判斷條件以前,先執行一次循環中的代碼。
repeat
{
print("Always executes at least once before the condition is considered")
}
while 1 > 2
複製代碼
return:馬上終止當前上下文,離開當前做用域,此外在返回時能夠額外攜帶一個值。
func doNothing()
{
return //直接離開當前上下文
let anInt = 0
print("This never prints (anInt)")
}
複製代碼
和
func returnName() -> String?
{
return self.userName //離開,並返回 userName 的值
}
複製代碼
switch:將給定的值與分支進行比較。執行第一個模式匹配成功的分支代碼。
let box = 1
switch box
{
case 0:
print("Box equals 0")
fallthrough
case 1:
print("Box equals 0 or 1")
default:
print("Box doesn't equal 0 or 1")
}
複製代碼
where:要求關聯類型必須遵照特定協議,或者類型參數和關聯類型必須保持一致。也能夠用於在 case 中提供額外條件,用於知足控制表達式。
where 從句能夠應用於多種場景。如下例子指明瞭 where 的主要應用場景,泛型中的模式匹配。
protocol Nameable
{
var name:String {get set}
}
func createdFormattedName(_ namedEntity:T) -> String where T:Equatable
{
//只有當實體同時遵照 Nameable 和 Equatable 協議的時候,才容許調用這個函數
return "This things name is " + namedEntity.name
}
複製代碼
和
for i in 0…3 where i % 2 == 0
{
print(i) //打印 0 和 2
}
複製代碼
while:循環執行特定的一段語句,直到條件不知足時,中止循環。
while foo != bar
{
print("Keeps going until the foo == bar")
}
複製代碼
Any:用於表示任意類型的實例,包括函數類型。
var anything = [Any]()
anything.append("Any Swift type can be added")
anything.append(0)
anything.append({(foo: String) -> String in "Passed in (foo)"})
複製代碼
as:類型轉換運算符,用於嘗試將值轉成其它類型。
var anything = [Any]()
anything.append("Any Swift type can be added")
anything.append(0)
anything.append({(foo: String) -> String in "Passed in (foo)" })
let intInstance = anything[1] as? Int
複製代碼
或者
var anything = [Any]()
anything.append("Any Swift type can be added")
anything.append(0)
anything.append({(foo: String) -> String in "Passed in (foo)" })
for thing in anything
{
switch thing
{
case 0 as Int:
print("It's zero and an Int type")
case let someInt as Int:
print("It's an Int that's not zero but (someInt)")
default:
print("Who knows what it is")
}
}
複製代碼
catch:若是在 do 中拋出一個錯誤,catch 會嘗試進行匹配,並決定如何處理錯誤。*我寫的一篇 Swift 錯誤處理的博客節選。
do
{
try haveAWeekend(4)
}
catch WeekendError.Overtime(let hoursWorked)
{
print("You worked (hoursWorked) more than you should have")
}
catch WeekendError.WorkAllWeekend
{
print("You worked 48 hours :-0")
}
catch
{
print("Gulping the weekend exception")
}
複製代碼
false:Swift 用於表示布爾值的兩個常量值之一,true 的相反值。
let alwaysFalse = false
let alwaysTrue = true
if alwaysFalse { print("Won't print, alwaysFalse is false 😉")}
複製代碼
is:類型檢查運算符,用於肯定實例是否爲某個子類類型。
class Person {}
class Programmer : Person {}
class Nurse : Person {}
let people = [Programmer(), Nurse()]
for aPerson in people
{
if aPerson is Programmer
{
print("This person is a dev")
}
else if aPerson is Nurse
{
print("This person is a nurse")
}
}
複製代碼
nil:在 Swift 中表示任意類型的無狀態值。
與 Objective-C 中的 nil 不一樣,Objective-C 中的 nil 表示指向不存在對象的指針。
class Person{}
struct Place{}
//任何 Swift 類型或實例能夠爲 nil
var statelessPerson:Person? = nil
var statelessPlace:Place? = nil
var statelessInt:Int? = nil
var statelessString:String? = nil
複製代碼
rethrows:指明當前函數只有當參數拋出 error 時,纔會拋出 error。
func networkCall(onComplete:() throws -> Void) rethrows
{
do
{
try onComplete()
}
catch
{
throw SomeError.error
}
}
複製代碼
super:在子類中,暴露父類的方法、屬性、下標。
class Person
{
func printName()
{
print("Printing a name. ")
}
}
class Programmer : Person
{
override func printName()
{
super.printName()
print("Hello World!")
}
}
let aDev = Programmer()
aDev.printName() //打印 Printing a name. Hello World!
複製代碼
self:任何類型的實例都擁有的隱式屬性,等同於實例自己。此外還能夠用於區分函數參數和成員屬性名稱相同的狀況。
class Person
{
func printSelf()
{
print("This is me: (self)")
}
}
let aPerson = Person()
aPerson.printSelf() //打印 "This is me: Person"
複製代碼
Self:在協議中,表示遵照當前協議的實體類型。
protocol Printable
{
func printTypeTwice(otherMe:Self)
}
struct Foo : Printable
{
func printTypeTwice(otherMe: Foo)
{
print("I am me plus (otherMe)")
}
}
let aFoo = Foo()
let anotherFoo = Foo()
aFoo.printTypeTwice(otherMe: anotherFoo) //打印 I am me plus Foo()
複製代碼
throw:用於在當前上下文,顯式拋出 error。
enum WeekendError: Error
{
case Overtime
case WorkAllWeekend
}
func workOvertime () throws
{
throw WeekendError.Overtime
}
複製代碼
throws:指明在一個函數、方法、初始化方法中可能會拋出 error。
enum WeekendError: Error
{
case Overtime
case WorkAllWeekend
}
func workOvertime () throws
{
throw WeekendError.Overtime
}
//"throws" 代表在調用方法時,須要使用 try,try?,try!
try workOvertime()
複製代碼
true:Swift 用於表示布爾值的兩個常量值之一,表示爲真。
let alwaysFalse = false
let alwaysTrue = true
if alwaysTrue { print("Always prints")}
複製代碼
try:代表接着調用的函數可能會拋出 error。有三種不一樣的使用方式:try,try?, try!。
let aResult = try dangerousFunction() //處理 error,或者繼續傳遞 error
let aResult = try! dangerousFunction() //程序可能會閃退
if let aResult = try? dangerousFunction() //解包可選類型。
複製代碼
_:用於匹配或省略任意值的通配符。
for _ in 0..<3
{
print("Just loop 3 times, index has no meaning")
}
複製代碼
另一種用法:
let _ = Singleton() //忽略不使用的變量
複製代碼
#available:基於平臺參數,經過 if,while,guard 語句的條件,在運行時檢查 API 的可用性。
if #available(iOS 10, *)
{
print("iOS 10 APIs are available")
}
複製代碼
#colorLiteral:在 playground 中使用的字面表達式,用於建立顏色選取器,選取後賦值給變量。
let aColor = #colorLiteral //建立顏色選取器
複製代碼
#column:一種特殊的字面量表達式,用於獲取字面量表示式的起始列數。
class Person
{
func printInfo()
{
print("Some person info - on column (#column)")
}
}
let aPerson = Person()
aPerson.printInfo() //Some person info - on column 53
複製代碼
#else:條件編譯控制語句,用於控制程序在不一樣條件下執行不一樣代碼。與 #if 語句結合使用。當條件爲 true,執行對應代碼。當條件爲 false,執行另外一段代碼。
#if os(iOS)
print("Compiled for an iOS device")
#else
print("Not on an iOS device")
#endif
複製代碼
#elseif:條件編譯控制語句,用於控制程序在不一樣條件下執行代碼。與 #if 語句結合使用。當條件爲 true,執行對應代碼。
#if os(iOS)
print("Compiled for an iOS device")
#elseif os(macOS)
print("Compiled on a mac computer")
#endif
複製代碼
#endif:條件編譯控制語句,用於控制程序在不一樣條件下執行代碼。用於代表條件編譯代碼的結尾。
#if os(iOS)
print("Compiled for an iOS device")
#endif
複製代碼
#file:特殊字面量表達式,返回當前代碼所在源文件的名稱。
class Person
{
func printInfo()
{
print("Some person info - inside file (#file)")
}
}
let aPerson = Person()
aPerson.printInfo() //Some person info - inside file /*代碼所在 playground 文件路徑*/
複製代碼
#fileReference:playground 字面量語法,用於建立文件選取器,選取並返回 NSURL 實例。
let fontFilePath = #fileReference //建立文件選取器
複製代碼
#function:特殊字面量表達式,返回函數名稱。在方法中,返回方法名。在屬性的 getter 或者 setter 中,返回屬性名。在特殊的成員中,好比 init 或 subscript 中,返回關鍵字名稱。在文件的最頂層時,返回當前所在模塊名稱。
class Person
{
func printInfo()
{
print("Some person info - inside function (#function)")
}
}
let aPerson = Person()
aPerson.printInfo() //Some person info - inside function printInfo()
複製代碼
#if:條件編譯控制語句,用於控制程序在不一樣條件下編譯代碼。經過判斷條件,決定是否執行代碼。
#if os(iOS)
print("Compiled for an iOS device")
#endif
複製代碼
#imageLiteral:playground 字面量語法,建立圖片選取器,選擇並返回 UIImage 實例。
let anImage = #imageLiteral //在 playground 文件中選取圖片
複製代碼
#line:特殊字面量表達式,用於獲取當前代碼的行數。
class Person
{
func printInfo()
{
print("Some person info - on line number (#line)")
}
}
let aPerson = Person()
aPerson.printInfo() //Some person info - on line number 5
複製代碼
#selector:用於建立 Objective-C selector 的表達式,能夠靜態檢查方法是否存在,並暴露給 Objective-C。
//靜態檢查,確保 doAnObjCMethod 方法存在
control.sendAction(#selector(doAnObjCMethod), to: target, forEvent: event)
複製代碼
#sourceLocation:行控制語句,能夠指定與原先徹底不一樣的行數和源文件名。一般在 Swift 診斷、debug 時使用。
#sourceLocation(file:"foo.swift", line:6)
//打印新值
print(#file)
print(#line)
//重置行數和文件名
#sourceLocation()
print(#file)
print(#line)
複製代碼
這些關鍵字,在處於對應上下文以外時,能夠用做標識符。
associativity:指明同一優先級的運算符,在缺乏大括號的狀況,按什麼順序結合。使用 left、right、none。
infix operator ~ { associativity right precedence 140 }
4 ~ 8
複製代碼
convenience:次等的便利構造器,最後會調用指定構造器初始化實例。
class Person
{
var name:String
init(_ name:String)
{
self.name = name
}
convenience init()
{
self.init("No Name")
}
}
let me = Person()
print(me.name)//打印 "No Name"
複製代碼
dynamic:指明編譯器不會對類成員或者函數的方法進行內聯或虛擬化。這意味着對這個成員的訪問是使用 Objective-C 運行時進行動態派發的(代替靜態調用)。
class Person
{
//隱式指明含有 "objc" 屬性
//這對依賴於 Objc-C 黑魔法的庫或者框架很是有用
//好比 KVO、KVC、Swizzling
dynamic var name:String?
}
複製代碼
didSet:屬性觀察者,當值存儲到屬性後立刻調用。
var data = [1,2,3]
{
didSet
{
tableView.reloadData()
}
}
複製代碼
final:防止方法、屬性、下標被重寫。
final class Person {}
class Programmer : Person {} //編譯錯誤
複製代碼
get:返回成員的值。還能夠用在計算型屬性上,間接獲取其它屬性的值。
class Person
{
var name:String
{
get { return self.name }
set { self.name = newValue}
}
var indirectSetName:String
{
get
{
if let aFullTitle = self.fullTitle
{
return aFullTitle
}
return ""
}
set (newTitle)
{
//若是沒有定義 newTitle,可使用 newValue
self.fullTitle = "(self.name) :(newTitle)"
}
}
}
複製代碼
infix:指明一個用於兩個值之間的運算符。若是一個全新的全局運算符被定義爲 infix,還須要指定優先級。
let twoIntsAdded = 2 + 3
複製代碼
indirect:指明在枚舉類型中,存在成員使用相同枚舉類型的實例做爲關聯值的狀況。
indirect enum Entertainment
{
case eventType(String)
case oneEvent(Entertainment)
case twoEvents(Entertainment, Entertainment)
}
let dinner = Entertainment.eventType("Dinner")
let movie = Entertainment.eventType("Movie")
let dateNight = Entertainment.twoEvents(dinner, movie)
複製代碼
lazy:指明屬性的初始值,直到第一次被使用時,才進行初始化。
class Person
{
lazy var personalityTraits = {
//昂貴的數據庫開銷
return ["Nice", "Funny"]
}()
}
let aPerson = Person()
aPerson.personalityTraits //當 personalityTraits 首次被訪問時,數據庫纔開始工做
複製代碼
left:指明運算符的結合性是從左到右。在沒有使用大括號時,能夠用於正確判斷同一優先級運算符的執行順序。
//"-" 運算符的結合性是從左到右
10-2-4 //根據結合性,能夠看作 (10-2) - 4
複製代碼
mutating:容許在方法中修改結構體或者枚舉實例的屬性值。
struct Person
{
var job = ""
mutating func assignJob(newJob:String)
{
self = Person(job: newJob)
}
}
var aPerson = Person()
aPerson.job //""
aPerson.assignJob(newJob: "iOS Engineer at Buffer")
aPerson.job //iOS Engineer at Buffer
複製代碼
none:是一個沒有結合性的運算符。不容許這樣的運算符相鄰出現。
//"<" 是非結合性的運算符
1 < 2 < 3 //編譯失敗
複製代碼
nonmutating:指明成員的 setter 方法不會修改實例的值,但可能會有其它後果。
enum Paygrade
{
case Junior, Middle, Senior, Master
var experiencePay:String?
{
get
{
database.payForGrade(String(describing:self))
}
nonmutating set
{
if let newPay = newValue
{
database.editPayForGrade(String(describing:self), newSalary:newPay)
}
}
}
}
let currentPay = Paygrade.Middle
//將 Middle pay 更新爲 45k, 但不會修改 experiencePay 值
currentPay.experiencePay = "$45,000"
複製代碼
optional:用於指明協議中的可選方法。遵照該協議的實體類能夠不實現這個方法。
@objc protocol Foo
{
func requiredFunction()
@objc optional func optionalFunction()
}
class Person : Foo
{
func requiredFunction()
{
print("Conformance is now valid")
}
}
複製代碼
override:指明子類會提供自定義實現,覆蓋父類的實例方法、類型方法、實例屬性、類型屬性、下標。若是沒有實現,則會直接繼承自父類。
class Person
{
func printInfo()
{
print("I'm just a person!")
}
}
class Programmer : Person
{
override func printInfo()
{
print("I'm a person who is a dev!")
}
}
let aPerson = Person()
let aDev = Programmer()
aPerson.printInfo() //打印 I'm just a person!
aDev.printInfo() //打印 I'm a person who is a dev!
複製代碼
postfix:位於值後面的運算符。
var optionalStr:String? = "Optional"
print(optionalStr!)
複製代碼
precedence:指明某個運算符的優先級高於別的運算符,從而被優先使用。
infix operator ~ { associativity right precedence 140 }
4 ~ 8
複製代碼
prefix:位於值前面的運算符。
var anInt = 2
anInt = -anInt //anInt 等於 -2
複製代碼
required:確保編譯器會檢查該類的全部子類,所有實現了指定的構造器方法。
class Person
{
var name:String?
required init(_ name:String)
{
self.name = name
}
}
class Programmer : Person
{
//若是不實現這個方法,編譯不會經過
required init(_ name: String)
{
super.init(name)
}
}
複製代碼
right:指明運算符的結合性是從右到左的。在沒有使用大括號時,能夠用於正確判斷同一優先級運算符的順序。
//"??" 運算符結合性是從右到左
var box:Int?
var sol:Int? = 2
let foo:Int = box ?? sol ?? 0 //Foo 等於 2
複製代碼
set:經過獲取的新值來設置成員的值。一樣能夠用於計算型屬性來間接設置其它屬性。若是計算型屬性的 setter 沒有定義新值的名稱,可使用默認的 newValue。
class Person
{
var name:String
{
get { return self.name }
set { self.name = newValue}
}
var indirectSetName:String
{
get
{
if let aFullTitle = self.fullTitle
{
return aFullTitle
}
return ""
}
set (newTitle)
{
//若是沒有定義 newTitle,可使用 newValue
self.fullTitle = "(self.name) :(newTitle)"
}
}
}
複製代碼
Type:表示任意類型的類型,包括類類型、結構類型、枚舉類型、協議類型。
class Person {}
class Programmer : Person {}
let aDev:Programmer.Type = Programmer.self
複製代碼
unowned:讓循環引用中的實例 A 不要強引用實例 B。前提條件是實例 B 的生命週期要長於 A 實例。
class Person
{
var occupation:Job?
}
//當 Person 實例不存在時,job 也不會存在。job 的生命週期取決於持有它的 Person。
class Job
{
unowned let employee:Person
init(with employee:Person)
{
self.employee = employee
}
}
複製代碼
weak:容許循環引用中的實例 A 弱引用實例 B ,而不是強引用。實例 B 的生命週期更短,並會被先釋放。
class Person
{
var residence:House?
}
class House
{
weak var occupant:Person?
}
var me:Person? = Person()
var myHome:House? = House()
me!.residence = myHome
myHome!.occupant = me
me = nil
myHome!.occupant // myHome 等於 nil
複製代碼
willSet:屬性觀察者,在值存儲到屬性以前調用。
class Person
{
var name:String?
{
willSet(newValue) {print("I've got a new name, it's (newValue)!")}
}
}
let aPerson = Person()
aPerson.name = "Jordan" //在賦值以前,打印 "I've got a new name, it's Jordan!"
複製代碼
哇噢!
這真是一次有趣的創做。我學會了好多在寫以前沒想到的東西。但我認爲這裏的訣竅並非要把它記住,而是把它當作一份能夠用於測驗的定義清單。
相反地,我建議你把這份清單放在手邊,並時不時地回顧一下。若是你能這樣作的話,下一次在不一樣場景下須要使用特定的關鍵字,你確定就能立刻回想起來並使用它啦。
下回再見咯。
本文由 SwiftGG 翻譯組翻譯,已經得到做者翻譯受權,最新文章請訪問 swift.gg。