博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Swift 中的关键字2
阅读量:3749 次
发布时间:2019-05-22

本文共 9707 字,大约阅读时间需要 32 分钟。

1.let关键字

用let修饰的变量会是一个不可变的常量, 也就是说不可以对它进行修改, 但如果用let修饰的常量是一个类, 那么我们可以对其所在的属性进行修改, 比如:

class PersonInfo {
let name = "xiaoming" var age = 18 var height = 170 var weight = 65}let personInfo = PersonInfo()personInfo.age += 1print("person age is \(personInfo.age).")// 输出的结果为: person age is 19.
1
2
3
4
5
6
7
8
9
10
11
12
13

这里边的name就是不可变的, 如果非要去改变, Xcode会建议你把let修改成var.

PS: 如果这个时候, 再声明一个person常量去引用personInfo, 那么person的所指向的内存块是和personInfo相同的.


2.var关键字

用var关键字声明的变量将会是一个可变的变量, 在这里, 我们并不会用var去引用一个类, 也没有必要, 继续拿上面的例子来说:

class PersonInfo {
let name = "xiaoming" var age = 18 var height = 170 var weight = 65}let personInfo = PersonInfo()personInfo.age += 1print("person age is \(personInfo.age).")
1
2
3
4
5
6
7
8
9
10
11
12

这里面的age就是属于var类型, 在初始化之后, 我们仍然可以给它进行修改.

PS: 如果这个时候, 我们用var修饰personMode变量去引用personInfo, 那么personMode和personInfo所指向的内存块并不同, personMode会将personInfo完整的拷贝一份, 然后放在另外一块内存块去管理.


3.class关键字

在Swift当中, 我们是使用Class关键字去声明一个类, 比如:

class PersonInfo {
// class body}
1
2
3

4.struct关键字

在Swift中, 如果我们需要声明一个结构体, 我们就需要使用到struct关键字, 比如:

struct PersonInfo {    // struct body} 
1
2
3

5.enum关键字

而我们需要声明枚举的时候, 我们就使用enum关键字, 比如:

enum PersonMode {    case zhangsan    case lisi    case wangwu(String)    case luoliu(String, Double, Int)} 
1
2
3
4
5
6

在Swift当中的enum和Objective-C并不一样, Swift的enum不会被隐式赋值为0, 1, 里面的zhangsan就是这个枚举分支的完整值, 并且在Swift中, 我们可以给enum case声明各种类型, 比如里面的case luoliu一样.

当然, 我们也可以给枚举值默认声明一个值, 但在枚举名之前, 要声明是什么类型, 比如:

enum Numbers: Int {    case One = 1, Two, Three, Four}let number = Numbers.One.rawValueprint(number) 
1
2
3
4
5
6
7

6.override关键字

在Swift中, 如果我们要重写某个方法, 或者某个属性的话, 我们需要在重写的变量前增加一个override关键字, 比如:

class Car {
var speed: Int { return 200 } func carSpeed() { print("Car max speed is \(speed)km 1 hours.") }}class NewCar: Car {
override var speed: Int { return 150 } override func carSpeed() { print("Car max speed is \(speed)km 1 hours.") }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

7.final关键字

上面我们介绍了override重写属性或者方法的关键字, 当然有重写, 肯定会有防止重写的关键字, 比如:

class Car {
var speed: Int { return 200 } final var carType: String { return "SUV" } func carSpeed() { print("Car max speed is \(speed)km 1 hours.") }}class NewCar: Car {
override var speed: Int { return 150 } override func carSpeed() { print("Car max speed is \(speed)km 1 hours.") } override var carType: String { return "MPV" }}// 这个时候, 下面这个override var carType: String{}属性就会报Var override a "final" var 的错误.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

8.subscript关键字

所谓的下标, 其实就可以快捷方式的设置或者获取对应的属性, 而不需要调用对应的方法去获取或者存储, 比如:

struct Animal {    let catType: String    subscript(animalName: String) -> String {        return "catType is \(animalName)."    }}let tiger = Animal(catType: "Tiger")print(tiger)// 输出的结果为: Animal(catType: "Tiger") 
1
2
3
4
5
6
7
8
9
10
11
12

9.mutating关键字

mutating这个关键字指的是可变, 只能用在struct和enum当中, 为的就是可以方便我们在特定环境下, 需要在struct中修改对应的属性值, 比如:

struct Animal {    let catType: String    subscript(animalName: String) -> String {        return "catType is \(animalName)."    }}let tiger = Animal(catType: "Tiger")print(tiger)// 输出的结果为: Animal(catType: "Tiger") 
1
2
3
4
5
6
7
8
9
10
11
12

10.static关键字

用static修饰的变量或者方法, 就会变成静态变量和静态方法, 并且保证在对应的作用域当中只有一份, 同时也不需要依赖实例化, 比如:

class Animals {
static var catName: String! func catTypeName() { _ = "Tiger" }}Animals.catName = "Tiger"print(Animals.catName)// 输出的结果为: Tiger
1
2
3
4
5
6
7
8
9
10
11
12
13
14

这里的catType被声明为static变量, 之后只要出现catType这个变量名, Xcode都会建议你用下标直接去声明, 因为需要保证在Animals这个类的作用域里, catType只保留一份.


11.lazy关键字

被lazy关键修饰的变量, 只有在第一次被调用的时候才会去计算它初始化值的属性, 比如:

class SuvCar {
var BydSuv = "S7"}class MpvCar {
lazy var suvCar = SuvCar() var mpvCars = [String]()}let mpvCar = MpvCar()mpvCar.mpvCars.append("CarOne")mpvCar.mpvCars.append("CarTwo")print("I have \(mpvCar.mpvCars.count) MPV.")// 输出的结果为: I have 2 MPV.print("I have a SUV Car, is \(mpvCar.suvCar.BydSuv)")// 输出的结果为: I have a SUV Car, is S7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

在这里需要注意两点:

  • 1.用lazy修饰的变量必须是用var声明的, 因为属性的初始值可能在实例构造完成之后才会得到。而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延迟属性。

  • 2.如果被lazy修饰的变量没有在初始化时就被多个线程调用, 那就没有办法保证它只被初始化一次了.


12.init关键字

在Swift 中也有对应的构造器, 来看看:

class Player {
var coinsInPurse: Int init(coins: Int) { coinsInPurse = 1000 }}
1
2
3
4
5
6
7

这样子coinsInPurse的值就为1000了.

还有一种用法, 就是在init后面加个”?”号, 表明该构造器可以允许失败

struct Animal {    let species: String    init?(species: String) {        if species.isEmpty { return nil }        self.species = species    }}let someCreature = Animal(species: "Giraffe")if let giraffe = someCreature {    print("An animal was initialized with a species of \(giraffe.species)")}let anonymousCreature = Animal(species: "")if anonymousCreature == nil {    print("The anonymous creature could not be initialized")} 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

13.convenient关键字

该关键字是用来修饰init的, 经过convenient修饰的init方法, 表明该init方式是比较次要, 辅助型的, 比如:

class Food {    var name: String    init(name: String) {        self.name = name    }    convenience init() {        self.init(name: "[Unnamed]")    }} 
1
2
3
4
5
6
7
8
9

14.required关键字

required也是用来修饰init方法的, 用required修饰说明该构造方法是必须实现的, 比如:

class SomeClass {
required init() { // init body }}
1
2
3
4
5

PS: 如果一个子类继承了父类required修饰的init方法, 就必须得去实现该init方法, 但子类可以觉得它之后继承于它的子类可以实现该方法.


15.deinit关键字

在Swift中, 有一个类似dealloc方法, 就是deinit, 但有一些区别, dealloc方法是在引用计数为0的时候, 也就是被释放的时候才会调用, 而deinit是在实例不再引用的自动调用, 并且不用手动去管理引用计数, 比如:

class Bank {
static var coinsInBank = 10_000 static func vendCoins(var numberOfConisToVend: Int) -> Int { numberOfConisToVend = min(numberOfConisToVend, coinsInBank) coinsInBank -= numberOfConisToVend return numberOfConisToVend } static func receiveCoins(coins: Int) { //print("coinsInBank = \(coinsInBank)") coinsInBank += coins }}class Player {
var coinsInPurse: Int init(coins: Int) { coinsInPurse = Bank.vendCoins(coins) } func winCoins(coins: Int) { coinsInPurse += Bank.vendCoins(coins) } deinit { Bank.receiveCoins(coinsInPurse) print("Player is nil.") }}var playerOne: Player? = Player(coins: 100)print("A new player has joined the game with \(playerOne!.coinsInPurse) coins.")// 输出的结果为: A new player has joined the game with 100 coinsprint("There are now \(Bank.coinsInBank) coins left in the bank.")// 输出的结果为: There are now 9900 coins left in the bank.playerOne?.winCoins(2_000)print("PlayerOne wn 2000 coins & now has \(playerOne!.coinsInPurse) coins.")// 输出的结果为: PlayerOne wn 2000 coins & now has 2100 coins.print("The bank now only has \(Bank.coinsInBank) coins left.")// 输出的结果为: The bank now only has 7900 coins left.playerOne = nil// 这个时候就会去调用deinit方法, 输出Player is nil.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

16.is关键字

在Swift中, is关键字是用来判断类型所使用的, 比如:

let number = ["xiaoming", 18]for item in number {    if item is Int {        print("item is Int type.")    } else if item is String {        print("item is String type")    }}// 输出的结果为: // item is String type.// item is Int type. 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

我们可以遍历一个[NSObject]类型的数组, 判断里面


17.throw, do-catch关键字

有关于throw, do-catch关键字的讲解在前面几章就有说明了


18.extension关键字

extension的作用是在不改变原来的类型或者协议基础下增加新的属性或者方法, 比如:

class Person {
var name = "xiaoming"}extension Person { var age: Int { return 20 }}let person = Person()print("person name is \(person.name), age is \(person.age).")// 输出的结果为:// person name is xiaoming, age is 20.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

19.protocol关键字

protocol关键字在Swift中也是属于协议的意思, 所谓的协议就是约束对象, 比如:

protocol Person {    var name: String { get }    var age: String { get }}class Xiaoming: Person {    var name: String { return "xiaoming" }    var age: String { return "20" }}class Laozhang: Person {    var name: String    var age: String    init(name: String, age: String) {        self.name = name        self.age = age    }} 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20.public关键字

public: 指的是可以访问在一个模块内的任何实体, 也可以通过导入该模块来访问, 也就是我们经常在Objective-C中经常需要导入的.h文件中的方法, 该关键字可以用来修饰变量, 方法, 类, 枚举, 结构体等等之类, 比如:

public struct Person {    // struct body}public enum CompassPoint {    // enum body}public class SomePublecClass {}public var somePublecVariable = 0 
1
2
3
4
5
6
7
8
9
10
11

21.internal关键字

internal: 指的是可以访问同一模块源文件中得任何实体, 但不能从模块的外部去访问该源文件中得实体, 同样, internal也可以修饰变量, 方法, 类, 枚举, 结构体等等之类等, 比如:

internal struct Person {    // struct body}internal enum CompassPoint {    // enum body}internal class SomePublecClass {}internal var somePublecVariable = 0 
1
2
3
4
5
6
7
8
9
10
11

22.private关键字

private: 指的是限制实体时能在源文件内部使用, 外部不能访问, private也同样可以用来修饰变量, 方法, 类, 枚举, 结构体等等之类, 比如:

private struct Person {    // struct body}private enum CompassPoint {    // enum body}private class SomePublecClass {}private var somePublecVariable = 0 
1
2
3
4
5
6
7
8
9
10
11

好了

转载地址:http://rpfsn.baihongyu.com/

你可能感兴趣的文章
USACO 2007 Open Gold/acwing2240:餐饮 (拆点+最大流)‘三分图匹配’
查看>>
那些年你不知道的C++STL进制转换函数
查看>>
区间和并问题 思路加模板整理(校门外的树)
查看>>
C++中next_permutation函数的使用方法、原理及手动实现
查看>>
网络流常用小技巧之 拆点
查看>>
掌握01分数规划 思想+应用模型总结
查看>>
最大权闭合子图
查看>>
最大密度子图
查看>>
最小权点覆盖集 与 最大权独立集
查看>>
POJ 2125 Destroying The Graph && Acwing 2325. 有向图破坏(拆点+最小权点覆盖集)
查看>>
Acwing 2326:王者之剑(网格图之网络流 最大权独立集)
查看>>
[网络流24题]洛谷P1251 / Acwing 2184: 餐巾计划问题(建图+拆点+最小费用最大流)
查看>>
NOI2008 & Acwing 969:志愿者招募(特殊的建图 与 无源汇|上下界|最小费用|可行流)
查看>>
计算几何基础知识整理大全 代码模板与证明过程 (直线、向量、多边形、三维计算几何、凸包、半平面交、最小圆覆盖)
查看>>
计算几何之 判断两线段是否相交 代码模板与证明
查看>>
三维计算几何之三维凸包 增量法
查看>>
MySQL变量,存储过程,函数,流程控制详解(小白都能懂哦)
查看>>
MySQL三大范式详解(小白也能懂哦)
查看>>
9篇小白都能懂系列博客学完MySQL基础
查看>>
还在为Linux入门发愁?
查看>>