Swift 学习记录 – 01
说明
为了写 safari 浏览器扩展,简单学习了一下 Swift 语言,这里记录下学习结果 — 仅能满足 safari Extension 的开发使用
资料
概览
一些开发中与 JavaScript 的主要不同,主要是梳理这篇文章 中的内容
-
let 声明常量 var 声明变量,初次赋值是会有类型推断,var 变量在二次赋值时不符合类型推断会报错
-
也可以不用类型推断,而是使用
:
直接声明变量或常量的类型let a: String = "123"
-
不会有隐式转换,需要手动将值转换为不同类型
let b: String = "startWith" + String(89)
-
"\()"
可以更方便的拼接字符串,并且可以帮助转换类型let a: Int = 89 let b: String = "startWith \(a)"
-
数组:
var list = [12, "123", "1241"] as [Any]
空数组var list = []
-
字典:
var map = ["name": "MyName", "age": 23] as [String : Any]
空字典var map = [:] as [String : Any]
-
如果一个变量的值是可选的,则再其类型后边加
?
例如:var a: String?
声明变量a 是 字符串类型或者是nil
-
??
用来给定默认值 例如print("name: \(value ?? "DEFAULT")")
在 value 为 nil 的情况下会输出??
后的 DEFAULT -
switch 语句中 case 部分可以比较各种数据类型,包括字典和数组,另外执行完一个 case 后即会跳出 switch 循环,不再需要手动 break
-
数组遍历
for item in list {}
, 字典遍历for (key, value) in map {}
-
while a < 100 {}
和repeat {} while a < 100
可以用作循环执行语句,后者可以保证至少一次的执行 -
序列区间
0..<4
表示[0, 4)
,0...4
表示[0, 4]
可以用作 for 循环,但是并不等于 数组 -
函数创建时定义需要形参的类型;函数调用时需要给传入的实参加 “标签” ;“标签” 通常就是形参的名称;标签并不能代替传入参数的顺序; 可以在定义函数时顺便定义函数调用时标签的名称,例如
func run(user person: String, _ day: String) -> String {}
在执行时run(user: "XiaoFang", "星期二")
_
定义形参时可以使用_
避免在函数调用时使用标签 -
可以使用元祖作为函数的返回值,例如
func run(user person: String, _ day: String?) -> (user: String, hasDay: Bool) {}
定义函数返回值为元祖类型,在函数中return ("userName", true)
这样,函数的返回值就可以使用result.hasDay
来处理返回值了 -
函数实参数量不定时
func run(person: String, days: Int...) -> String {}
这样 person 后的实参都会被收集到 数组 days 中,run(person: "Xiao fei", days: 12, 123, 434)
-
函数的地位与 JavaScript 中的函数类似,也就是说,函数可以作为参数传递;函数可以作为返回值;可以使用闭包
-
函数的简写:使用
{}
开启一个闭包,闭包中使用in
操作符分割形参与实际处理语句, 如果是一个表达式语句则会被作为返回值返回,如果有多个表达式或者语句怎需要 return 否则返回空numbers.map({ (number: Int) -> Int in // 可以没有类型声明 let result = 3 * number return result }) // 也可以进一步简写 number.map({ number in 3 * number })
-
class 类
class Parent {
var shapeNumber = 0 // 变量声明 + 赋值
var name: String // 如果只声明类型不赋值,那这个变量需要在 init 中赋值一次,否则报错
// 初始化器
init(name: String?) {
// self 可以理解为类的实例,类比 JavaScript 中类的 this
self.name = name ?? "DEFAULT_NAME"
}
// 反初始化器, 用来在释放对象前做些清理的事情
deinit {
}
func increase(num: Int) {
self.shapeNumber += num
}
func pri() {
// 实际上类的属性与方法都可以直接访问,不需要经过 self, 只有 init 初始化器中需要 self 做区分
print(name)
print(shapeNumber == self.shapeNumber)
}
}
// 类的实例化
var shape = Shape(name: "Xiao Bai");
print(shape.name)
shape.increase(num: 90)
shape.pri()
// 类的继承直接在声明类的时候用 : 标注要继承的类
class Child: Parent {
var originAge: Int = 0;
// 子类的初始化器中可以通过 super 调用父类的初始化器
// 如果不定义子类的初始化器,创建实例时需要按照父类的初始化器进行
init(name: String, age: Int) {
self.originAge = age
super.init(name: name)
}
// 可以定义 getter setter 的计算属性
var age: Int {
get {
return 2 * originAge
}
// set 中会默认有一个 名为 newValue 的变量作为 set 的“赋值”,也可以在 () 中显示的给这个赋值命名
set (newAge) {
originAge = newAge - 3
}
}
// 子类中如果定义与父类同名的方法则需要加上 override 关键字
override func increase(num: Int) {
shapeNumber = shapeNumber + num + 10
}
}
var child = Child(name: "DD", age: 10)
- swift 也可以使用类似 TS 的可选链运算符
[obj]?.[prop]
例如let sideLength = optionalSquare?.sideLength
optionalSquare 如果有 sideLength 则直接返回,否则返回值为 nil
其他
1. 数据类型
// …
2. 基本运算符
运算符与 javascript 基本一致
- 赋值运算符
a = b; let (x, y) = (2, 3)
- 算数运算符
+ - * /
与 javascript 一样 - 余数运算符
%
- 组合赋值
a += 2
即为a = a + 2
简写 - 比较运算符
- 相等 ( a == b )
- 不相等 ( a != b )
- 大于 ( a > b )
- 小于 ( a < b )
- 大于等于 ( a >= b )
- 小于等于 ( a <= b )
- 判断对象引用 (a === b 、a !== b)
- 三元运算符
var a = isTrue ? "TRUE" : "FALSE"
- 合并空值运算符
var a = value ?? "defaultValue"
会判断 ?? 前的值 如果为空值则返回后边的值 - 区间运算符
1...5 1..>5
通常用来处理数组 - 逻辑运算符 && 与、|| 或、!非