1.常量和变量
常量用let
修饰,定义之后值不以修改,变量用var
修饰,定义之后值可以修改。
Swift中定义常量和变量不需要写数据类型, 编译器会根据后面的数据的真实类型自动推导
在Swift中,运算符不能直接跟在变量或常量的后面
var a = 10
// 每一条语句后面可以不写分号,写上也不会报错,如果同一行有多条语句,那么每条语句后面必须写上分号
let a = 10; let a = 9.0
// option+点击变量名称 查看方法或者变量
// 不同类型之间不能直接进行计算,需要做转换
let x:Int = 10 // 指定数据类型
let y = 0.5
print(x + Int(y)) (print 相当于 OC中的NSLog, print性能更好)
// => 10
命名规则: 可以使用几乎任何字符作为常量和变量名,包括Unicode,但是不能包含数字符号、箭头、无效的Unicode、横线-、制表符、且不能以数字开头。
let 中 = 10
print("中 = ", 中)
// => 中 = 10
var 下 = 1.9
下 = 2.0
print("下 = \(下)")
// => 下 = 2.0
2.数据类型转换
Swift中不存在隐式类型转换,所有的类型转换都必须是显示的
let num1 = 10
let num2 = 9.9
let sum = num1 + Int(num2)
print((num1, "+", num2, "=", sum)
// => 10 + 9.9 = 19
print(Double(num1) + num2)
// => 19.9
3. 可选项
使用Optional
或者?
,表示该常量/变量可能有值,也可能没有值。
// 1.定义可选项用 `Optional` 或者 `?`
/**
* 使用可选项类型如果直接打印可选类型,打印出来的值会被Optional包裹
* !代表告诉编译器可选类型中一定有值,强制解析,如果可选类型中没有值又进行了强制解析,程序会报错
*/
let x:Optional = 10
let y:Int? = 20
print(x)
// => Optional(10)
print(x!)
// => 10
print(y)
// => Optional(20)
// 2.可选项参与计算的时候需要解包,使用 `!` 解包,从可选值中取出对应的非空值
print(x! + y!)
// => 30
// 3.可选绑定
// 会将num中的值取出赋值给year,如果不为nil,就进入{}
let num:Optional = "2021"
if let year = num {
print(year)
}
// => 2021
4. 逻辑分支
Swift中的if的使用方式基本上和OC一致
Swift中的if中可以省略()但是必须加上{}
在C和OC中有非0即真;在Swift中条件只能放bool值,取值true/false
let n1 = 10
if (n1 == 10) {
print("相等")
}
if n1 == 10 {
print("相等")
}
三目的写法与OC基本一致
var a = 10; var b = 11
a > b ?print("a > b"):print("a < b")
// => a < b
?? 是一个简单的三目,如果有值,就使用值,如果没值,就使用 ?? 后面的值
let c :Int? = nil
print(Int(n1) + (c ?? 0))
// => 10
let d :Int? = 4
print(Int(n1) + (c ?? 0))
// => 14
switch
1.后面的()可以省略,每一个分支至少需要一条指令
2.OC中的switch如果没有break会继续执行,Swift中不需要添加break,如果需要多值用‘,’隔开
3.OC中如果要在case中定义变量,必须加上{}确定作用域,Switch中不用
4.OC中default的位置可以随便,只有case都不满足才会执行,Swift中的default只能放在最后
5.OC中的default可以省略,Swift中一般情况不能省略
6.OC中只针对整型进行分支,swift中可以针对任意类型的值
let num = "June"
switch num {
case "January":
let a = 31
print("一月" + a.description + "天")
case "February":
print("二月")
case "March":
print("三月")
case "April","May","June":
print("第二季度")
default:
print("none")
}
// -> 第二季度
for循环
条件(0...5)之间不能出现空格
// 0..<5,表示从0开始到5之间(不包含5)的数[0,5)
for i in 0..<5 {
print(i)
}
// => 0 1 2 3 4
// 0...5,表示从0开始到5之间(包含5)的数[0,5]
for i in 0...5{
print(i)
}
// => 0 1 2 3 4 5
// _代表忽略,如果不要参数就可以使用_
for _ in 0..<5 {
print("1234")
}
// => 1234(打印5次)
repeat...while 相当于OC中的do...while
var n2 = 0
repeat {
print(n2)
n2 += 1 // Swift3.0中已经删除了 ++/--
} while n2 < 10
// -> 0
// -> 1
// -> 2
// -> 3
// -> 4
// -> 5
// -> 6
// -> 7
// -> 8
// -> 9
5.数组
数组的定义和初始化 OC: @[], Swift: []
- OC 可变数组 NSMutableArray 不可变 NSArray
- Swift 可变数组 var 不可变 let
var array1 = ["Jan","Feb","Mar","Apr","May","Jun"]
print(array1)
// => ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
// 初始化 [类型]()
var array2 = [String]()
array2.append("a")
print(array2)
// => ["a"]
var array3 = [Int]()
array3.append(12)
print(array3)
// => [12]
// 2.基本数据类型不需要包装 OC @[@(1),@(2)]
let array3 = [1,2,3,4,5]
print(array3)
// => [1, 2, 3, 4, 5]
// 3.数组的遍历
// a>按照下标遍历
for i in 0..<array1.count{
print(array1[i])
}
// => Jan
// => Feb
// => Mar
// => Apr
// => May
// => Jun
for i in array1 {
print(i)
}
// => 同上
// enumerated()函数 遍历 同时遍历下标和内容
for e in array1.enumerated() {
print("\(e.offset) \(e.element)")
}
// => 0 Jan
// => 1 Feb
// => 2 Mar
// => 3 Apr
// => 4 May
// => 5 Jun
// enum 遍历 同时遍历下标和内容
for (index,value) in array1.enumerated() {
print("\(index) \(value)")
}
// => 同上
// 反序遍历
for e in array1.reversed(){
print(e)
}
// => Jun
// => May
// => Apr
// => Mar
// => Feb
// => Jan
// 4.数组添加元素 .append
array2.append("b")
array2.append("c")
print(array2)
// => ["a", "b", "c"]
// 5.数组修改元素
array2[1] = "d"
print(array2)
// => ["a", "d", "c"]
// 6.数组删除元素 .remove
array2.remove(at: 2)
print(array2)
// => ["a", "d"]
// 7.数组的合并 保证两个数组类型一致
array1 += array2
print(array1)
// => ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "a", "d"]
6.字典
字典的定义 OC @{} Swift中和数组一样使用 []
1.定义字典
var dict1 = [String:AnyObject]() // 初始化一个空字典
var dict = ["123":"壹贰叁", "456":"肆伍陆", "789": 10] as [String : Any]
print(dict["123"])
// => Optional("壹贰叁")
2.字典的添加元素 (有则更新键值对,没有则添加)
dict["age"] = "你猜"
dict["789"] = 789
3.字典元素的修改
dict.updateValue(19, forKey: "789")
4.字典元素的删除
dict["789"] = nil
print(dict)
// => ["456": "肆伍陆", "age": "你猜", "123": "壹贰叁"]
dict.removeValue(forKey: "123")
5.字典的遍历
dict = ["789":"10", ""age"":"你猜", "456":"肆伍陆", "123":"壹贰叁"]
for value in dict {
print(value)
}
// => (key: "789", value: 10)
// => (key: "age", value: "你猜")
// => (key: "456", value: "肆伍陆")
// => (key: "123", value: "壹贰叁")
// 利用元祖类型遍历字典,会自动将字典中的key赋值给元祖中的第一个变量,将value赋值给元祖中的第二个变量
// 第一个是key,第二个是value
for (key, value) in dict {
print("\(key),\(value)")
}
// => 123,壹贰叁
// => age,你猜
// => 456,肆伍陆
// => 789,10
6.字典的合并
let dict2 = ["吃饭了":"好的","吃的啥":"你猜"]
for (key, value) in dict2 {
dict[key] = value
}
print(dict)
// => ["123": "壹贰叁", "吃的啥": "你猜", "789": 10, "age": "你猜", "吃饭了": "好的", "456": "肆伍陆"]
7.字符串
OC中的字符串是NSString, Swift中的字符串是String
OC中的字符串是一个对象,继承于NSObject; Swift中的字符串是一个结构体
Swift中的字符串的性能比OC中的高
定义字符串
var str: String = "Hellow"
print(str.count) // str的长度
// => 6
String转化NSString
let ocString = str as NSString
print("ocString = \(ocString.length)")
// => ocString = 6
字符串的遍历(OC不支持遍历)
for s in str {
print(s)
}
// => H
// => e
// => l
// => l
// => o
// => w
字符串的拼接 \(常量/变量)
var str: String = "Hellow"
let a2 = "World!"
str = "\(str)\(a2)\(20)"
print(str)
// => HellowWorld!20
str += "下班了"
print(str)
// => HellowWorld!20下班了
字符串的格式化
所有的值都必须放到数组中,只有一个值也需要放到数组中
let date = String(format: "%@年%@月%@日 %@:%@:%02d", arguments: ["2021", "07", "21", "19", "33", 56])
print(date)
// => 2021年07月21日 19:33:56
字符串的截取
let str = "Hellow World!"
let sub1 = str.prefix(3)
let sub2 = str.suffix(4)
print(sub1)
// => Hel
print(sub2)
// => rld!
let sub = String(str[str.index(str.startIndex, offsetBy: 2)..<str.index(str.startIndex, offsetBy: 5)])
print(sub)
// => llo
8.函数
函数数定义格式:
语义:将(参数列表)计算的结果返回给 -> 返回值
func 函数名称(参数列表) -> 返回值
{
执行代码
}
// 没有返回值没有参数,如果函数没有返回值就写Void
func say() -> Void
{
print("hello")
}
say()
// => hello
func say() -> ()
{
print("hello")
}
say()
// => hello
func say()
{
print("hello")
}
say()
// => hello
// 有返回值没有参数
func getNum() -> Int
{
return 999
}
print(getNum())
// => 999
// 有参数没有返回值
func sum2(a: Int, b: Int)
{
print(a + b)
}
sum2(a: 2, b: 3)
// => 5
外部参数:就是在形参前面加一个名字
外部参数不会影响函数内部计算
x, y称之为外部参数,a, b称之为内部参数
func sum2(x a: Int, y b: Int)
{
print(a + b)
}
sum2(x: 1, y: 2)
// => 3
外部参数如果使用 _ ,在外部调用函数时会省略形参的名字
func sum2(_ a: Int, _ b: Int) -> Int
{
return a + b
}
print(sum2(10, 2))
// => 12
// 有参数有返回值
func sum2(a: Int, b: Int) -> Int
{
return a + b
}
print(sum2(a: 10, b: 20))
// => 30
函数的默认值
给参数设置默认值,在调用的时候如果不设定值的,使用默认值。
func sum2(a: Int = 11, b: Int = 12) -> Int
{
return a + b
}
print(sum2())
// => 23
9.闭包
闭包就是能够读取其他函数内部变量的函数,可以理解成定义在一个函数内部的函数。
简单的说它就是一个代码块,用{}包起来,他可以用在其他函数的内部,将其他函数的变量作为代码块的参数传入代码块中,在Swift中多用于回调。这个跟Object-C中的block是一样的。
闭包的使用场景:
- 异步执行回调
- 控制器件回调
- 自定义视图回调
闭包基本格式:
{
(形参列表) -> ()
in
需要执行的代码
}
有参数有返回值
let aaa = { (x : Int, y: Int) -> Int in
return x + y
}
print(aaa(5, 5))
// => 10
有参数无返回值
let bbb = {(x: Int?) -> () in
print((x ?? 0))
}
bbb(100)
// => 100
无参数无返回值
let ccc = {() -> () in
print("无参数无返回值的闭包")
}
ccc()
// => 无参数无返回值的闭包
let abc = {
print("闭包")
}
// => 闭包
10.元组
元组(tuples)是把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型
元组类型的值的语法格式为:(元素1, 元素2, ..., 元素n)。
1. 使用索引值访问(索引值从0开始)
let turple = ("张三", 19, true)
print(turple.0)
print(turple.1)
print(turple.2)
// => 张三
// => 19
// => true
2. 为元组中的元素指定名字,然后使用指定的名字访问。
let turple2 = (name: "张三", age: 18, isMarried: true)
print(turple2.name)
// => 张三
let turple: (name: String, age: Int, isMarried: Bool) = ("张三", 19, true)
print(turple.age)
// => 19
把元组中的元素分解成多个变量或常量,然后使用变量名或常量名访问。
可以使用这种方式同时声明并初始化多个变量或常量。
let (name, age, isMarried) = ("张三", "19", true)
print(name);
print(age)
print(isMarried)
// => 张三
// => 19
// => true
使用元组类型来定义元组变量
var score : (Int, Int, String, Double)
为元组变量赋值时必须为所有成员都指定值
score = (98, 89, "及格", 20.4)
print(score.0)
print(score.2)
// => 98
// => 及格
元组的成员又是元组
var test:(Int, (Int, String))
test = (20, (15, "老张"))
print(test.1.1)
// => 老张
将元组拆分成多个变量, 数量必须相同, 忽略元组用_
let turple: (name: String, age: Int, isMarried: Bool) = ("张三", 19, true)
var (height, weight, _) = turple
print(height)
print(weight)
// => 张三
// => 19