在Swift 中,不像Objective-C一样,有些关键字可以找到对应的解释,这里我就列一下常用的关键字详解,陆续会有增加.
1.let关键字
用let修饰的变量会是一个不可变的常量,也就是说不可以对它进行修改,但如果用let修饰的常量是一个类,那么我们可以对其所在的属性进行修改,比如:
class PersonInfo {
let name = "xiaoming"
var age = 18
var height = 170
var weight = 65
}
let personInfo = PersonInfo()
personInfo.age += 1
print("person age is \(personInfo.age).")
// 输出的结果为: person age is 19.
这里边的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 += 1
print("person age is \(personInfo.age).")
这里面的age就是属于var类型,在初始化之后,我们仍然可以给它进行修改.
PS: 如果这个时候,我们用var修饰personMode变量去引用personInfo,那么personMode和personInfo所指向的内存块并不同,personMode会将personInfo完整的拷贝一份,然后放在另外一块内存块去管理.
3.class关键字
在Swift当中,我们是使用Class关键字去声明一个类,比如:
class PersonInfo {
// class body
}
4.struct关键字
在Swift中,如果我们需要声明一个结构体,我们就需要使用到struct关键字,比如:
struct PersonInfo {
// struct body
}
5.enum关键字
而我们需要声明枚举的时候,我们就使用enum关键字,比如:
enum PersonMode {
case zhangsan
case lisi
case wangwu(String)
case luoliu(String,Double,Int)
}
在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.rawValue
print(number)
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.")
}
}
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 的错误.
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")
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")
10.static关键字
用static修饰的变量或者方法,就会变成静态变量和静态方法,并且保证在对应的作用域当中只有一份,同时也不需要依赖实例化,比如:
class Animals {
static var catName: String!
func catTypeName() {
_ = "Tiger"
}
}
Animals.catName = "Tiger"
print(Animals.catName)
// 输出的结果为: Tiger
这里的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.用lazy修饰的变量必须是用var声明的,因为属性的初始值可能在实例构造完成之后才会得到。而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延迟属性。
@H_501_404@2.如果被lazy修饰的变量没有在初始化时就被多个线程调用,那就没有办法保证它只被初始化一次了.
@H_501_404@
12.init关键字
在Swift 中也有对应的构造器,来看看:
class Player {
var coinsInPurse: Int
init(coins: Int) {
coinsInPurse = 1000
}
}
这样子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")
}
13.convenient关键字
该关键字是用来修饰init的,经过convenient修饰的init方法,表明该init方式是比较次要,辅助型的,比如:
class Food {
var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "[Unnamed]")
}
}
14.required关键字
required也是用来修饰init方法的,用required修饰说明该构造方法是必须实现的,比如:
class SomeClass {
required init() {
// init body
}
}
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 coins
print("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.
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.
我们可以遍历一个[NSObject]类型的数组,判断里面
17.throw,do-catch关键字
有关于throw,do-catch关键字的讲解在前面几章就有说明了1.Swift 错误信息处理
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.
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
}
}
20.public关键字
public: 指的是可以访问在一个模块内的任何实体,也可以通过导入该模块来访问,也就是我们经常在Objective-C中经常需要导入的.h文件中的方法,该关键字可以用来修饰变量,方法,类,枚举,结构体等等之类,比如:
public struct Person {
// struct body
}
public enum CompassPoint {
// enum body
}
public class SomePublecClass {}
public var somePublecVariable = 0
21.internal关键字
internal: 指的是可以访问同一模块源文件中得任何实体,但不能从模块的外部去访问该源文件中得实体,同样,internal也可以修饰变量,结构体等等之类等,比如:
internal struct Person {
// struct body
}
internal enum CompassPoint {
// enum body
}
internal class SomePublecClass {}
internal var somePublecVariable = 0
22.private关键字
private: 指的是限制实体时能在源文件内部使用,外部不能访问,private也同样可以用来修饰变量,比如:
private struct Person {
// struct body
}
private enum CompassPoint {
// enum body
}
private class SomePublecClass {}
private var somePublecVariable = 0
好了,这次就讲到这里,如果还有其他关键,我们陆续在该文章里更新.