Swift学习
基础部分
- 变量声明方式不同,使用
let
,var
关键字,类型推断非常多,需要注意 - 基础类型的使用,如
Int
,String
,Float
,Double
,Boolean
,注意数值类型的默认类型,3.14
默认是Double
类型 - 元组类型数据(tuples)
- 引入
Optional
类型,默认为nil
,可对其有无值进行判断,同时引入可选类型绑定(Optional Binding
)if
let
/var
, 空合运算符??
语法糖,进行nil
判断,可选类型解析?
,!
进行解包 - 错误处理
- 决断assert,用于调试
基本运算符
- 运算符基本所有的语言都通用,不过
swift
含有可选类型,故引入了空合运算符??
,?
,!
对可选类型进行拆包 - 区间运算符 ..., ..< 语法糖,多用于循环和数组下标
字符串和字符
- String 是值类型,使用Unicode编码,而NSString使用UTF-16编码
- 引入多行字符串开关引号,前后都是三个引号
"
- 字符串拼接使用
+
或append
- 字符串插值,在字符串中是
\(value)
将value
的值插入到字符串中 - 其中字符的使用,多使用字符串索引,
String.Index
, 操作起来比较复杂,和java
中操作字符串一样,是比较少使用,但是需要时间学习的功能 - 字符串的比较
- 前后缀的使用
集合类型
数组 Array
声明数组
var arr: Array = Array()
// or
var arr: [String] = [String]()
其中Array
和[String]
是数组的类型,Array
和[String]()
是变量的声明,统一都是类型()的形式来声明变量
数组的简单使用
使用方法和java
差不多,增删改查,只是函数名不同而已
数组的遍历
使用foreach
遍历
for item in shoppingList {
print(item)
}
同时需要索引
for (index, item) in shoppingList.enumerated() {
print("Item \(item)'s index is \(index).")
}
集合 Sets
其中的类型需要保证是可哈希的
哈希值
swift
基本类型都实现了Hashtable
协议,如果自定义的类型需要实现Hashtable
和Equatable
类型
基本操作
除了不能使用下标进行访问,其他操作基本和Array
相同
集合间操作
运算
-
intersection
两个集合相同的部分 -
symmetricDifference
两个集合不同的部分 -
union
两个集合合并 -
subtracting
前者集合减去和后者集合相同的部分
比较
-
isSubset
前者是否是后者的子集 -
isSuperset
前者是否是后者的父集 -
isStrictSubset
前者是否是后者的子集,并且两者不等 -
isStrictSuperset
前者是否是后者的父集,并且两者不等 -
isDisjoint
是否两者没有相同的元素
字典 Dictionary
声明字典
var dic: Dictionary = Dictionary()
// or
var dic: [Int: String] = [Int: String]()
基本操作
字典的操作也是增删改查,如函数updateValue
, removeValue
字典遍历
// 遍历key和value
for (key, value) in dic {
print("key is \(key), value is \(value)")
}
// 遍历key
for key in dic.keys {
print("key is \(key)")
}
// 遍历value
for value in dic.values {
print("value is \(value)")
}
控制流
for-in
- 主要用于集合的遍历
- 用于循环求值
集合遍历的使用方法在上一节集合类型中已经涉及了,这里主要说一下循环求值,和类C语言中有些不一样,其主要使用Range
区间的概念
for index in 1...5 {
print("\(index)")
}
int end = 10;
for index in 5...end {
print("\(index)")
}
for minute in stride(from: 0, to: 60, by: 5) {
print("\(minute)") // 0,5,10...55 不包含to的值
}
for hour in stride(from: 3, through: 12, by: 3) {
print("\(hour)") // 3,6,9,12 包含through的值
}
while, repeat-while
使用方法和C中的while
, do-while
一样
if
使用方法和C中的if
一样
switch
swift中的switch
非常强大,不仅可以匹配Int
, String
, 还可以匹配各种条件,可以认为,swift
想让它来简化多个if-else
。
基本概念和用法
switch-case
并不需要break
中断,默认是自动中断的,如果需要多个case
贯通,那么需要使用fallthrough
连接,并且多个case
并不能合并一起使用,而是将多个匹配放在同一个case
中,使用逗号,
隔开,或者多个case
使用逗号,
不是:
隔开。
区间、元组
case
匹配可以是一个区间,元组。
值绑定
和if
一样,case
匹配也可以使用值绑定,不要看着官方文档上比较复杂,实际原理是一样的
同时,引入了where
关键字,对值绑定进行匹配
控制转换语句
-
continue
: 和C中使用方式一样 -
break
: 和C中使用方式一样 -
fallthrough
: 因为swift
自动中断case
,所以需要贯通时,使用fallthrough
关键词 -
label
: 带标签的语句,极其少的使用,最好不要使用
guard
guard
关键字时候swift
引用的,和go
中处理io
关闭的思想是一样的,在声明时就写好关闭操作,避免遗忘,guard
用于当条件不满足时提前退出,使用方法可以认为时候if-else
的简化版。
检查版本
if #available(iOS 10, macOS 10.12, *) {
// 使用iOS, mac10.12之后的API
} else {
// 使用旧API
}
函数
定义
函数是完成一段特定任务的独立代码片段。
swift
中函数参数是在()
内,和C
, Java
不同的是参数类型是在参数后以:
隔开,返回类型在()
后面,用->
隔开,如果没有返回值,可以省略-> Void
,接着就是{}
包括的函数体
分类
- 无参数函数
- 多参数函数
- 无返回值函数
- 多重返回值函数
- 可选元组返回类型函数
记住,函数的参数可以是可选类型,返回值类型也可以是可选类型,返回类型如果是元组,那么整个元组也可以是可选类型
参数标签
在swift
中,一个参数可以有两个名字,一个是在调用时使用的,一个是在函数体内部使用的,如果只声明一个参数名,那么默认内外使用的参数名是一样的。在声明外部使用的参数名时,可以使用_
代替,表示在调用时,不声明参数名。
故,在swift
中,_
一律表示可以省略
默认参数值
在Java
中经常会碰见为了接受多个参数,而且某些参数如果不指定的情况下,给一个默认值的情况,从而会定义多个同名不同参的方法,使用默认参数值就是为了避免定义多个函数。
在声明参数时,可以为函数指定默认值,在调用函数时,可以不传该参数,表示使用默认参数值。如下
func defaultParamFunc(value: Int, defaultValue: Int = 5) {
// do something
}
defaultParamFunc(value: 10)
defaultParamFunc(value: 10, defaultValue: 15)
可变参数
和C
中使用相同
输入输出函数
可以认为是将参数的指针传递进去,调用输入输出函数时,使用&
修饰参数。如下
// 声明时,参数类型使用inout修饰
func swapTwoInteger(_ a: inout Int, _ b: inout Int) {
let tmp = a
a = b;
b = tmp
}
var a = 10
var b = 5
// 调用时,使用&修饰参数值
swapTwoInteger(&a, &b)
print("a = \(a), b = \(b)")
// a = 5, b = 10
函数类型
函数本身具有类型,如() -> Void
是一个无参数,无返回值(返回值为Void
)的函数。那么可以这样认为,一个常量或者变量,有名字和类型,而函数,也有名字和类型,这个默认的名字,就是声明函数时的名字。
这样函数就是一种类型,函数名就是变量名/常量名,将函数作为函数的参数,或者返回类型,就不会变得那么别扭了。
嵌套函数
即闭包,默认的域包括外部函数的临时变量和外部函数可以使用的变量
闭包
前言
闭包的语法比较多,会简单的使用,在使用中逐步深入即可。
定义
闭包是自包含的函数代码块,可以在代码中被传递和使用。
形式
在函数章节中介绍的全局和嵌套函数实际上也是特殊的闭包,闭包采用如下三种形式之一:
- 全局函数是一个有名字但不会捕获任何值的闭包
- 嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包
- 闭包表达式是一个利用轻量级语法所写的可以捕获其上下文中变量或常量值的匿名闭包
闭包表达式
闭包表达式的一般形式:使用in
分割
{ (parameter) -> return type in
statement
}
// 如下
let sortedNames = names.sorted(by: {(s1: String, s2: String) -> Boolean in
return s1 > s2
})
// 参数类型推断,省略参数类型
let sortedNames = names.sorted(by: {(s1, s2) -> Boolean in
return s1 > s2
})
// 返回类型退款,省略返回类型
let sortedNames = names.sorted(by: { s1, s2 in
return s1 > s2
})
// 单表达式省略`return`
let sortedNames = names.sorted(by: {s1, s2 in s1 > s2})
// 参数名称缩写
let sortedNames = names.sorted(by: {$0 > $1})
// 运算符方法
let sortedNames = names.sorted(by: >)
尾随闭包
// 省略参数标签,省略`()`
let sortedNames = names.sorted {s1, s2 in s1 > s2}
值捕获
闭包可以在其被定义的上下文中捕获常量或变量。即使定义这些常量和变量的原作用域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。