Swift 中的关键字详解
要學(xué)習(xí)Swift這門語言,就必須先了解Swift的關(guān)鍵字及對(duì)應(yīng)的解釋。這里就列一下在Swift中常用到的關(guān)鍵字。
關(guān)鍵字是類似于標(biāo)識(shí)符的保留字符序列,除非用重音符號(hào)(`)將其括起來,否則不能用作標(biāo)識(shí)符。關(guān)鍵字是對(duì)編譯器具有特殊意義的預(yù)定義保留標(biāo)識(shí)符。常見的關(guān)鍵字有以下4種。
與聲明有關(guān)的關(guān)鍵字:class、deinit、enum、extension、func、import、init、let、protocol、static、struct、subscript、typealias和var。
與語句有關(guān)的關(guān)鍵字:break、case、continue、default、do、else、fallthrough、if、in、for、return、switch、where和while。
表達(dá)式和類型關(guān)鍵字:as、dynamicType、is、new、super、self、Self、Type、__COLUMN__、__FILE__、__FUNCTION__和__LINE__。
在特定上下文中使用的關(guān)鍵字:associativity、didSet、get、infix、inout、left、mutating、none、nonmutating、operator、override、postfix、precedence、prefix、rightset、unowned、unowned(safe)、unowned(unsafe)、weak和willSet。
常見關(guān)鍵字的介紹:
1、class
在Swift當(dāng)中, 我們使用Class關(guān)鍵字去聲明一個(gè)類和聲明類方法, 比如:
class Person {
// 給方法添加class關(guān)鍵字表示類方法
class func work() {
print("Type Method: Person: 學(xué)生.")
}
}
這樣我們就聲明了一個(gè)Student類。
2、let
Swift里用let修飾的變量會(huì)是一個(gè)不可變的常量,即我們不可以對(duì)它進(jìn)行修改。(注意:我們用let修飾的常量是一個(gè)類, 我們可以對(duì)其所在的屬性進(jìn)行修改)比如:
class Student {
let name = "xiaoMing"
var age = 16
var height = 160
}
let studen = Student();
studen.age += 2
print("student age is (studen.age)")
//輸出結(jié)果為student age is 18
在Student類里name是不可變的,如果要對(duì)它進(jìn)行修改就要將let改為var。注意:如果這個(gè)時(shí)候, 再聲明一個(gè)Student常量去引用student, 那么studen1所指向的內(nèi)存塊是和studen相同的.
3、var
Swift中用var修飾的變量是一個(gè)可變的變量,即可以對(duì)它進(jìn)行修改。注意:我們不會(huì)用var去引用一個(gè)類, 也沒有必要。比如:
class Student {
let name = "xiaoMing"
var age = 16
var height = 160
}
let studen = Student();
studen.age += 2
var student2 = studen;
student2.age -= 3
print("student age is (studen.age)")
print("student2 age is (student2.age)")
/**
輸出結(jié)果為
student age is 15
student2 age is 15
*/
由輸出結(jié)果可以看出他們所指向的內(nèi)存塊都是同一個(gè)。
4、struct
在Swift中, 我們使用struct關(guān)鍵字去聲明結(jié)構(gòu)體,Swift中的結(jié)構(gòu)體并不復(fù)雜,與C語言的結(jié)構(gòu)體相比,除了成員變量,還多了成員方法。使得它更加接近于一個(gè)類。個(gè)人認(rèn)為可以理解為是類的一個(gè)輕量化實(shí)現(xiàn)。比如:
struct Person {
var name:String
var age:Int
func introduce(){
print("我叫:(name),今年(age)歲")
}
}
var person = Person(name: "xiaoMing",age: 20)
person.name = "xiaoMing"
print("person.name = (person.name)")
person.introduce()
/**
輸出結(jié)果為:
person.name = xiaoMing
我叫:xiaoMing,今年20歲
*/
語法與C語言或者OC類似,Swift中的結(jié)構(gòu)體,在定義成員變量時(shí)一定要注明類型。另外要注意一下的是,結(jié)構(gòu)體屬于值類型,而Swift中的類屬于引用類型。他們?cè)趦?nèi)存管理方面會(huì)有不同。
5.enum
在Swift中, 我們使用enum關(guān)鍵字去聲明枚舉。枚舉是一種常見的數(shù)據(jù)類型,他的主要功能就是將某一種有固定數(shù)量可能性的變量的值,以一組命名過的常數(shù)來指代。比如正常情況下方向有四種可能,東,南,西,北。我們就可以聲明一組常量來指代方向的四種可能。使用枚舉可以防止用戶使用無效值,同時(shí)該變量可以使代碼更加清晰。比如:
enum Orientation:Int{
case East
case South
case West
case North
}
/**
或者
enum Orientation:Int{
case East,South,West,North
}
*/
print(Orientation.East.rawValue)
/**
輸出結(jié)果 0
*/
注意:我們?cè)诙x枚舉時(shí),一定要指定類型,否則在使用時(shí)就會(huì)報(bào)錯(cuò)。枚舉類型的值如果沒有賦值,他就按照默認(rèn)的走,可以賦予我們自己想要的值。
6、final
Swift中,final關(guān)鍵字可以在class、func和var前修飾。表示 不可重寫 可以將類或者類中的部分實(shí)現(xiàn)保護(hù)起來,從而避免子類破壞。詳細(xì)了解可以去看看(Swift - final關(guān)鍵字的介紹,以及使用場(chǎng)景
)。比如:
class Fruit {
//修飾詞 final 表示 不可重寫 可以將類或者類中的部分實(shí)現(xiàn)保護(hù)起來,從而避免子類破壞
final func price(){
print("price")
}
}
class Apple : Fruit {//類繼承
// //重寫父類方法
// override func price() {
// print("重寫父類的price 方法")
// }
}
這里重寫price()這個(gè)函數(shù)就會(huì)報(bào)錯(cuò)。
7、override
在Swift中, 如果我們要重寫某個(gè)方法, 或者某個(gè)屬性的話, 我們需要在重寫的變量前增加一個(gè)override關(guān)鍵字, 比如:
class Fruit {
var sellPrice : Double = 0
func info() -> () {
print("fruit")
}
//修飾詞 final 表示 不可重寫 可以將類或者類中的部分實(shí)現(xiàn)保護(hù)起來,從而避免子類破壞
final func price(){
print("price")
}
}
class Apple : Fruit {//類繼承
func eat () -> () {
print("apple22222")
}
//重寫父類方法
override func info() {
print("重寫父類的info 方法00000")
}
//重寫父類的屬性 重寫父類的屬性或者方法要使用關(guān)鍵字 override 進(jìn)行修飾
override var sellPrice: Double {
get {
print("kkkkkkk(super.sellPrice)")
return super.sellPrice + 3
}
set {
print("qqqqq")
super.sellPrice = newValue * newValue
}
}
}
let app = Apple()
app.info()
app.sellPrice = 20.0
let adb = app.sellPrice
print("adb == (adb)")
/**
輸出結(jié)果為:
重寫父類的info 方法00000
qqqqq
kkkkkkk400.0
adb == 403.0
*/
8、subscript
在Swft中,subscript關(guān)鍵字表示下標(biāo),可以讓class、struct、以及enum使用下標(biāo)訪問內(nèi)部的值。其實(shí)就可以快捷方式的設(shè)置或者獲取對(duì)應(yīng)的屬性, 而不需要調(diào)用對(duì)應(yīng)的方法去獲取或者存儲(chǔ), 比如官網(wǎng)的一個(gè)實(shí)例:
struct Matrix {
let rows: Int, columns: Int
var grid: [Double]
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
grid = Array(repeating: 0.0, count: rows * columns)
}
func indexIsValid(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
subscript(row: Int, column: Int) -> Double {
get {
assert(indexIsValid(row: row, column: column), "Index out of range")
return grid[(row * columns) + column]
}
set {
assert(indexIsValid(row: row, column: column), "Index out of range")
grid[(row * columns) + column] = newValue
}
}
}
var matrix = Matrix(rows: 2, columns: 2)
matrix[0, 1] = 1.5
matrix[1, 0] = 3.2
print("matrix == (matrix)")
/**
打印結(jié)果:
matrix == Matrix(rows: 2, columns: 2, grid: [0.0, 1.5, 3.2000000000000002, 0.0])
*/
9、static
Swift中,用static關(guān)鍵字聲明靜態(tài)變量或者函數(shù),它保證在對(duì)應(yīng)的作用域當(dāng)中只有一份, 同時(shí)也不需要依賴實(shí)例化。注意:(用static關(guān)鍵字指定的方法是類方法,他是不能被子類重寫的)比如:
class Person {
// 給方法添加class關(guān)鍵字表示創(chuàng)建類方法
class func work() {
print("Type Method: Person: 學(xué)生.")
}
// 使用static關(guān)鍵字創(chuàng)建類方法
static func ageOfPerson(name: String) {
print("Type Method: Person name: (name)")
}
// 可以和類方法重名, 以及一樣的參數(shù).
func nameOfPerson(name: String) {
print("Instance Method: person name (name)")
}
}
class Student: Person {
//注意 子類Student的實(shí)例方法work(), 和父類的類方法work()沒有關(guān)系, 二者不在同一個(gè)級(jí)別上, 不存在同名問題.
func work() {
print("Instance Method: Student: University Student")
}
}
10、mutating
Swift中,mutating關(guān)鍵字指的是可變即可修改。用在structure和enumeration中,雖然結(jié)構(gòu)體和枚舉可以定義自己的方法,但是默認(rèn)情況下,實(shí)例方法中是不可以修改值類型的屬性。為了能夠在實(shí)例方法中修改屬性值,可以在方法定義前添加關(guān)鍵字mutating。比如:
struct rect {
var width = 0,height = 0
mutating func changeRect(x:Int, y:Int) {
self.width += x
self.height += y
}
}
enum Direction {
case Top, Left, Right, Bottom
mutating func lookDirection() {
switch self {
case .Top:
self = .Top
case .Left:
self = .Left
case .Right:
self = .Right
case .Bottom:
self = .Bottom
}
print("self === (self)")
}
}
var re = rect( 5, height: 5)
re.changeRect(x: 32, y: 15)
print("re = (re)")
/**
打印結(jié)果為:re = rect( 37, height: 20)
*/
var dir = Direction.Left
dir.lookDirection()
/**
打印結(jié)果為:self === Left
*/
11、typealias
在Swift中,使用關(guān)鍵字typealias定義類型別名(typealias就相當(dāng)于objective-c中的typedef),就是將類型重命名,看起來更加語義化。比如:
typealias Width = CGFloat
typealias Height = CGFloat
func rectangularArea(Width, height:Height) -> Double {
return Double(width*height)
}
let area: Double = rectangularArea( 10, height: 20)
print(area)
/**
結(jié)果為:200.0
*/
12、lazy
在Swift中,lazy關(guān)鍵修飾的變量, 只有在第一次被調(diào)用的時(shí)候才會(huì)去初始化值(即懶加載)。比如:
lazy var first = NSArray(objects: "1","2")
注意:用lazy修飾的變量必須是用var聲明的, 因?yàn)閷傩缘某跏贾悼赡茉趯?shí)例構(gòu)造完成之后才會(huì)得到。而常量屬性在構(gòu)造過程完成之前必須要有初始值,因此無法聲明成延遲屬性。如果被lazy修飾的變量沒有在初始化時(shí)就被多個(gè)線程調(diào)用, 那就沒有辦法保證它只被初始化一次了。
13、init
在Swift 中,init關(guān)鍵字也表示構(gòu)造器。比如:
class PerSon {
var name:String
init?(name : String) {
if name.isEmpty { return nil }
self.name = name
}
}
let person = PerSon.init(name: "xiaoQiang")
print("person is name (String(describing: person?.name))")
/**
打印結(jié)果為:person is name Optional("xiaoQiang")
*/
在例子里在init后面加個(gè)”?”號(hào), 表明該構(gòu)造器可以允許失敗。
14、required
在Swift里,required是用來修飾init方法的,說明該構(gòu)造方法是必須實(shí)現(xiàn)的。比如:
class PerSon {
var name:String
required init(name : String) {
self.name = name
}
}
class Student: PerSon {
required init(name:String) {
super.init(name: name)
}
}
從上面的代碼示例中不難看出,如果子類需要添加異于父類的初始化方法時(shí),必須先要實(shí)現(xiàn)父類中使用required修飾符修飾過的初始化方法,并且也要使用required修飾符而不是override。
注意: (1)required修飾符只能用于修飾類初始化方法。
(2)當(dāng)子類含有異于父類的初始化方法時(shí)(初始化方法參數(shù)類型和數(shù)量異于父類),子類必須要實(shí)現(xiàn)父類的required初始化方法,并且也要使用required修飾符而不是override。
(3)當(dāng)子類沒有初始化方法時(shí),可以不用實(shí)現(xiàn)父類的required初始化方法。
15、extension
在swift中,extension與Objective-C的category有點(diǎn)類似,但是extension比起category來說更加強(qiáng)大和靈活,它不僅可以擴(kuò)展某種類型或結(jié)構(gòu)體的方法,同時(shí)它還可以與protocol等結(jié)合使用,編寫出更加靈活和強(qiáng)大的代碼。它可以為特定的class, strut, enum或者protocol添加新的特性。當(dāng)你沒有權(quán)限對(duì)源代碼進(jìn)行改造的時(shí)候,此時(shí)可以通過extension來對(duì)類型進(jìn)行擴(kuò)展。extension有點(diǎn)類似于OC的類別 -- category,但稍微不同的是category有名字,而extension沒有名字。在Swift 中的可以擴(kuò)展以下幾個(gè):
(1)定義實(shí)例方法和類型方法
(2)添加計(jì)算型屬性和計(jì)算靜態(tài)屬性
(3)定義下標(biāo)
(4)提供新的構(gòu)造器
(5)定義和使用新的嵌套類型
(6)使一個(gè)已有類型符合某個(gè)接口
比如:
// 添加計(jì)算屬性
extension Double {
var km: Double { return self * 1_000.0 }
var m: Double { return self }
var cm: Double { return self / 100.0 }
}
class Person {
var name:String
var age:Int = 0
init?(name:String) {
if name.isEmpty {
return nil
}
self.name = name
}
}
extension Person {
//添加方法
func run() {
print("走了50公里")
}
}
let oneInch = 25.4.km
print("One inch is (oneInch) meters")
/**
輸出結(jié)果:One inch is 25400.0 meters
*/
let person = Person.init(name: "xiaom")
person?.run()
/**
輸出結(jié)果:走了50公里
*/
想要了解詳情可以去看看這篇文漲(apple documents - extensions)
16、convenient
swift中,使用convenience修飾的構(gòu)造函數(shù)叫做便利構(gòu)造函數(shù) 。便利構(gòu)造函數(shù)通常用在對(duì)系統(tǒng)的類進(jìn)行構(gòu)造函數(shù)的擴(kuò)充時(shí)使用。便利構(gòu)造函數(shù)有如下幾個(gè)特點(diǎn):
(1)便利構(gòu)造函數(shù)通常都是寫在extension里面
(2)便利函數(shù)init前面需要加載convenience
(3)在便利構(gòu)造函數(shù)中需要明確的調(diào)用self.init()
比如:
extension UIButton{
//swit中類方法是以class開頭的方法,類似于oc中+開頭的方法
class func createButton(imageName:String)->UIButton{
let btn=UIButton()
btn.setImage(UIImage(named:imageName), for: .normal)
btn.sizeToFit()
return btn
}
/*
convenience:便利,使用convenience修飾的構(gòu)造函數(shù)叫做便利構(gòu)造函數(shù)
便利構(gòu)造函數(shù)通常用在對(duì)系統(tǒng)的類進(jìn)行構(gòu)造函數(shù)的擴(kuò)充時(shí)使用。
*/
convenience init(imageName:String,bgImageName:String){
self.init()
if !imageName.isEmpty {
setImage(UIImage(named:imageName), for: .normal)
}
if !imageName.isEmpty {
setBackgroundImage(UIImage(named:bgImageName), for: .normal)
}
sizeToFit()
}
}
let btn = UIButton.init(imageName: "huanying", bgImageName: "")
btn.frame = CGRect.init(x: 10, y: 120, 100, height: 30)
btn.backgroundColor = UIColor.red
self.view.addSubview(btn)
17、deinit
在Swift中,deinit屬于析構(gòu)函數(shù),當(dāng)對(duì)象結(jié)束其生命周期時(shí)(例如對(duì)象所在的函數(shù)已調(diào)用完畢),系統(tǒng)自動(dòng)執(zhí)行析構(gòu)函數(shù)。和OC中的dealloc 一樣的,通常在deinit和dealloc中需要執(zhí)行的操作有:
(1)對(duì)象銷毀
(2)KVO移除
(3)移除通知
(4)NSTimer銷毀
18、fallthrough
swift語言特性switch語句的break可以忽略不寫,滿足條件時(shí)直接跳出循環(huán).fallthrough的作用就是執(zhí)行完當(dāng)前case,繼續(xù)執(zhí)行下面的case.類似于其它語言中省去break里,會(huì)繼續(xù)往后一個(gè)case跑,直到碰到break或default才完成的效果。比如:
var myClass = MyClass(parm: 9)
let index = 15
switch index {
case 1 :
print( "index is 100")
case 10,15 :
print( "index is either 10 or 15")
case 5 :
print( "index is 5")
default :
print( "default case")
}
/**
輸出結(jié)果:index is either 10 or 15
*/
let index = 15
switch index {
case 100 :
print( "index is 100")
fallthrough
case 10,15 :
print( "index is either 10 or 15")
fallthrough
case 5 :
print( "index is 5")
default :
print( "default case")
}
/**
打印結(jié)果:
index is either 10 or 15
index is 5
*/
19、protocol
在Swift中,protocol關(guān)鍵字也是屬于協(xié)議。比如:
protocol PersonProtocol {
var height: Int { get set }
var weight: Int { get }
func getName()
func getSex()
func getAge(age: Int)
}
struct Student: PersonProtocol {
var height = 178
var weight = 120
func getName() {
print("MelodyZhy")
}
func getSex() {
print("boy")
}
func getAge(age: Int) {
print("age = (age)")
}
}
var stu = Student()
let height1 = stu.height
stu.height = 180
print("height1 = (height1) height2 = (stu.height)")
/**
輸出結(jié)果:
height1 = 178 height2 = 180
*/
20、open
在Swift中,open修飾的對(duì)象表示可以被任何人使用,包括override和繼承。例如:
import UIKit
// 在本類外的范圍外可以被繼承
open class ParentClass1: NSObject {
// 這個(gè)方法在任何地方都可以被override
open func abc() {
print("abc")
}
}class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//這里可以調(diào)用module1的方法
let child = ChildrenClass1.init()
child.abc()
/**
打印結(jié)果:abc
*/
}
class ChildrenClass1: ParentClass1 {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
21、public
在Swift中,public表示公有訪問權(quán)限,類或者類的公有屬性或者公有方法可以從文件或者模塊的任何地方進(jìn)行訪問。但在其他模塊(一個(gè)App就是一個(gè)模塊,一個(gè)第三方API, 第三等方框架等都是一個(gè)完整的模塊)不可以被override和繼承,而在本模塊內(nèi)可以被override和繼承。
import UIKit
// 在module1外的范圍外可以被繼承
public class ParentClass1: NSObject {
// 這個(gè)方法在任何地方都可以被override
public func abc() {
print("abc")
}
}class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//這里可以調(diào)用module1的方法
let child = ChildrenClass1.init()
child.abc()
/**
打印結(jié)果:abc11
*/
}
class ChildrenClass1: ParentClass1 {
override func abc() {
print("abc11")
}
func run() -> Void {
print("run")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
22、internal
在Swift中,public表示內(nèi)部的訪問權(quán)限。即有著internal訪問權(quán)限的屬性和方法說明在模塊內(nèi)部可以訪問,超出模塊內(nèi)部就不可被訪問了。在Swift中默認(rèn)就是internal的訪問權(quán)限。
import UIKit
// 在module1外的范圍外可以被繼承
internal class ParentClass1: NSObject {
// 這個(gè)方法在任何地方都可以被override
func abc() {
print("abc")
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//這里可以調(diào)用module1的方法
let child = ChildrenClass1.init()
child.abc()
/**
打印結(jié)果:abc11
*/
}
class ChildrenClass1: ParentClass1 {
override func abc() {
print("abc11")
}
func run() -> Void {
print("run")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
23、private
在Swift中,private私有訪問權(quán)限。被private修飾的類或者類的屬性或方法可以在同一個(gè)物理文件中訪問。如果超出該物理文件,那么有著private訪問權(quán)限的屬性和方法就不能被訪問。比如:
import UIKit
// 在module1外的范圍外可以被繼承
internal class ParentClass1: NSObject {
// 這個(gè)方法在任何地方都可以被override
private func abc() {
print("abc")
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//這里可以調(diào)用module1的方法
let child = ChildrenClass1.init()
child.abc()
/**
打印結(jié)果:abc11
*/
}
class ChildrenClass1: ParentClass1 {
/**
這里就會(huì)報(bào)錯(cuò)
*/
override func abc() {
print("abc11")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
24、fileprivate
在Swift中,fileprivate訪問級(jí)別所修飾的屬性或者方法在當(dāng)前的Swift源文件里可以訪問。比如:
import UIKit
// 在module1外的范圍外可以被繼承
internal class ParentClass1: NSObject {
// 這個(gè)方法在任何地方都可以被override
fileprivate func abc() {
print("abc")
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//這里可以調(diào)用module1的方法
let child = ChildrenClass1.init()
child.abc()
/**
打印結(jié)果:abc11
*/
}
class ChildrenClass1: ParentClass1 {
override func abc() {
print("abc11")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
說明:5種修飾符訪問權(quán)限排序open> public > interal > fileprivate > private。
參考文獻(xiàn):
http://www.jianshu.com/p/6daa3e309235
http://blog.csdn.net/qq350116542/article/details/50629260
http://www.jianshu.com/p/1ae8c364954a
總結(jié)
以上是生活随笔為你收集整理的Swift 中的关键字详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hotspot GC Root 对应调用
- 下一篇: 魔兽世界怀旧服雷布里斯库比格特掉落什么?