Swift基础
Playground
元组
`let http404Error = (404, "Not Found")
let (code, msg) = http404Error
let (onlyCode, _ ) = http404Error
let http200Status = (code: 404, description: "OK")`
流程控制
if
只支持 bool 类型
switch
区间匹配、元组匹配
// 区间匹配
let count = 2
switch count {
case 0:
print("")
case 1...2:
print("")
case 3..<7:
print("")
case 7...:
print("")
default:
print("")
}
// 元组匹配
let point = (1, 1)
switch point {
case (0, 0):
print("")
case (0...3, 0...3):
print("")
case (_, 0):
print("")
default:
print("")
}
值绑定
// 值绑定
switch point {
case (let x, 0):
print("\(x)")
case let (x, y):
print("\(x)\(y)")
}
where子句
// where子句
switch point {
case (let x, 0):
print("\(x)")
case let (x, y) where x == y:
print("\(x)\(y)")
default:
print("")
}
var numbers = [-10, 0, 1, 2]
for x in numbers where x > 0 {
}
方法
// 标准函数定义
func a(i: Int, j: Int) -> (Int, Int) {
return (i, j)
}
func a1(i: Int, j: Int) -> Int {
return i + j
}
// 省略返回值
func a2(i: Int, j: Int) {
}
// 参数标签
func a3(i param1: Int, j param2: Int) -> Int {
return param1 + param2
}
func a3(_ i: Int, _ j: Int) -> Int {
return i + j
}
// 默认参数值
func a4(i: Int = 10, j: Int) {
}
// 可变参数
func a5(i: Int...) {
for x in i {
print("\(x)")
}
}
inout
// inout
func swapValues(_ v1: inout Int, _ v2: inout Int) {
let temp = v1
v1 = v2
v2 = temp
}
- 可变参数不能标记为 inout
- inout 参数不能有默认值
- inout 参数的本质是地址传递
- inout 参数只能传入可以被多次赋值的 我认为,本质上针对 inout 的限制原因都在第4条,其他只是引申出来的。
汇编小技巧:
- lea 是传递地址:leaq xxx %yyy,值xxx 作为地址
- %xxx 都是寄存器
- (xxx) 表示作为地址:movq xxx (yyy),把xxx复制给地址为yyy的内存
函数重载
规则:
- 函数名相同
- 参数个数不同,或者参数类型不同,或者参数标签不同
- 返回值是否相同不影响 我认为就是指编译器是否能准确识别出你要调用哪个函数
函数类型
// 函数类型
func a6() {} // ()->()或者()->Void
func a7(a: Int, b: Int) -> Int {
return a
} // (Int, Int) -> Int
枚举
关联值vs.原始值
关联值:将枚举的成员值跟其他类型的数据关联存储在一起 原始值:枚举成员可以使用相同类型的默认值预先关联,这个默认值叫做原始值
隐式原始值
如果枚举的原始值类型是Int、String,swift会自动分配原始值
递归枚举
枚举占用的空间大小
enum Password {
case number(Int, Int, Int, Int)
case other
}
MemoryLayout<Password>.side // 真实使用了33个字节,Int占8个字节,1个字节表明枚举成员类型,
MemoryLayout<Password>.aligmn // 8,对齐参数
MemoryLayout<Password>.stride // 40个字节,size是33,因为对齐参数是8,所以真实分配的存储空间大小是40个字节
可选项
1、可选项绑定
2、空合并运算符??
public func ?? <T>(optional:T?, defaultValue:@autoclosure ()->T?)->T?
public func ?? <T>(optional:T?, defaultValue:@autoclosure ()->T)->T
3、隐式解包
为什么会有隐式解包?
为了解决限制严格的初始化过程造成的不方便。如果成员变量被声明成T,那么在初始化完成前,它一定要被赋上值,否则只能声明为T?
但实际上有时候不想/不能在初始化时就赋值,但是可以肯定的是在使用前一定有值。
所以就有了隐式解包T!
结构体
编译器会根据情况,为结构体生成多个初始化器,宗旨是:保证所有成员都有初始值
struct Point {
var x: Int = 10
var y: Int
}
ok的:
var p1 = Point(x: 10, y: 10)
var p3 = Point(y: 10)
编译不能通过:
var p2 = Point(x: 10)
var p4 = Point()
struct Point {
var x: Int?
var y: Int?
}
都ok:
var p1 = Point(x: 10, y: 10)
var p3 = Point(y: 10)
var p2 = Point(x: 10)
var p4 = Point()
类
编译器没有为类自动生成可以传入成员值的初始化器