Swift 大约历经 4 年的开发期,2014 年 6 月发步
- 苹果宣称 Swift 的特点是:快速、现代、安全、互动,而且明显优于 Objective-C 语言
- 可以使用现有的 Cocoa 和 Cocoa Touch 框架
- Swift 取消了 Objective C 的指针及其他不安全访问的使用
- 舍弃 Objective C 早期应用 Smalltalk 的语法,全面改为句点表示法
- 提供了类似 Java 的名字空间(namespace)、泛型(generic)、运算对象重载(operator overloading)
- Swift 被简单的形容为 “没有 C 的 Objective-C”(Objective-C without the C)
目录
- 常量和变量
- 基本数据类型
- 类型转换
- Bool类型
- 元祖
- 可选值
- 字符和字符串
- 字符串常用方法
- 运算符
- 数组的基本使用
- 数组其他操作
- 字典
- if
- while循环
- for循环
- break-continue
- Switch
- 函数定义
- 闭包
- 枚举
- 结构体
- 懒加载
常量和变量
- var 定义变量,设置之后可以修改
- let 定义常量,设置之后不可以修改
变量
01> 先定义,再初始化
var num: Int
num = 10
02> 定义的同时进行初始化
var num2 = 20
// 如果要显式的指定变量的类型,可以在定义是使用 var 变量名: 类型 = 值
var num3: Int = 30
常量
Swift中的常量必须在定义时初始化
格式:let num : Int
let num4 = 30
let num5: Int = 30
常量&变量的使用原则:尽量先用 let,只有需要变的时候,再用 var,能够更加安全
基本数据类型
整型
var intValue: Int = 10
浮点型
var floatValue1:Double = 99.99 // 表示64位浮点数
var floatValue2:Float = 8.8 // 表示32位浮点数
如果按长度分,swift中的长短比OC更加精确
var intValue1:Int8 = 8
var intValue2:Int16 = 16
var intValue3:Int32 = 32
var intValue4:Int64 = 64
有无符号划分,默认是有符号的
- 无符号(UInt8/UInt16/UInt32/UInt64)
var uintValue:UInt8 = 100
注意:无符号的数比有符号的数取值范围更大,因为符号位也用来存储值
类型转换
隐式类型转换
OC:
int intValue = 10;
double doubleValue = (double)intValue
Swift 不允许隐式类型转换,但可以使用显式类型转换(强制类型转换)
var intValue: Int = 10
// var doubleValue: Double = intValue 报错
var doubleValue: Double
doubleValue = Double(intValue)
// 注意:Double()不会修改 intValue 的值,而是通过 intValue 的值生成一个临时的值赋值给 doubleValue
print(intValue) // 10
print(doubleValue) // 10.0
Bool类型
C语言的Bool类型是非0即真
OC语言的Bool类型是typedef signed char BOOL
Swift 引入了真正的Bool类型
真:true
假:false
let isOpen = true
if isOpen {
print("打开")
} else {
print("关闭")
}
元祖
将多个相同或者不同类型的值用一个小括号括起来就是一个元祖
- 元祖其实和结构体很像,只是不需要提前定义类型。
- 元祖其实是复合类型,小括号中可以写任意类型
元祖的其他定义方式:
01>指明元祖内部每个元素的类型
let student1: (String,Int,Double) = ("Larry",20,59.5)
02>指明对应元祖元素的名称
let student2 = (name:"Vivian",age:18,score:99.5)
03>通过指定的名称提取元祖对应的值,会将对应位置的值,赋值给对应位置的名称
let(name,age,score) = ("Eric",26,88.5)
04>如果不关心元祖中某个值,可以利用通配符(_)来忽略提取
let(name1,age1,_) = ("Owen",30,77.5)
可选值
可选值:optionals 有两种状态
- 1.有值
- 2.没有值,没有值就是 nil
// 有值
var optionalValue1: Int? = 9
// 没有值
var optionalValue2: Int?
var optionalValue3: Int? = nil
可选类型的值的提取(强制解析)”!”
var optValue2: Int? = 8
var result: Int = optValue2!
可选绑定:
为了更安全的解析可选类型的值,一般情况下使用可选绑定
如果optValue没有值就不会做任何操作,如果optValue有值会返回true并将optValue的值赋值给result,然后执行大括号值的内容
var optValue: Int? = 88;
if let result3 = optValue {
print(optValue) // Optional(88)
}
字符和字符串
字符
单个字符
var charValue1:Character = "a"
var charValue2:Character = "王" // 正确
字符串
字符是单个字符的集合,字符串是多个字符的集合,想要存放多个字符需要使用字符串
var stringValue3 = "abc"
var stringValue4:String = "abcdef"
字符串常用方法
计算字符串的长度
var stringValue = "swift学习"
print(stringValue.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
// 打印结果11 字符占一个字节,汉子占3个字节
字符串拼接
var str1 = "abc"
var str2 = "123"
var str = str1 + str2
print(str) // abc123
格式化字符串
var name = "Mazy"
var str3 = "\(name) have fun"
print(str3) // Mazy have fun
字符串比较
Swift: (== / != / >= / <=)
var str4 = "have fun"
var str5 = "have fun"
if str4 == str5 {
print("相等")
} else {
print("不相等")
}
var str6 = "abc"
var str7 = "abd"
if str6 >= str7 {
print("大于或者等于")
} else {
print("小于")
}
判断前后缀
var urlString = "http://www.baidu.com"
if urlString.hasPrefix("http") {
print("是URL")
}
if urlString.hasSuffix(".com") {
print("是域名")
}
大小写转换
var str8 = "Study Swift"
print(str8.lowercaseString) // study swift
print(str8.uppercaseString) // STUDY SWIFT
转换为基本数据类型
var str9 = "12306"
// 如果string不能转换为整数,那么可选类型返回nil
// 当str9 = "12306a" 不能转换为整型,所以转换结果为nil
var number: Int? = Int(str9)
if (number != nil) {
print(number) // Optional(12306)
}
运算符
算术运算符
+ - * / % += 1 -= 1
var result = 10 + 10
print(result) // 20
result = 10 - 10
print(result) // 0
result = 10 * 10
print(result) // 100
result = 10 / 10
print(result) // 1
result = 10 % 10
print(result) // 0
取模
print(10 % 3.0) // 3.0
// 10 / 3.5 = 2-->3
// 如果分子和分母有一个是小数,最后的结果就是浮点型
自增自减
- Swift 2.0 可以用 ++ 和 –
- Swift 3.0 以后用 += 1 和 -= 1
var number = 10
number += 1
print(number)
number -= 1
print(number)
赋值运算
= += -= /= *= %=
var number1 = 10
number1 = 20
print(number1) // 20
number1 += 10
print(number1) // 30
number1 -= 10
print(number1) // 20
number1 *= 10
print(number1) // 100
number1 /= 10
print(number1) // 20
number1 %= 10
print(number1) // 0
关系运算符
- 运算结果是Bool值,基本语法和OC一样
> < >= <= == != ?:(三目运算符)
var result1:Bool = 20 > 10
print(result1)
// MARK: - 三目运算符
var result2 = 20 > 10 ? 20 : 10
print(result2)
逻辑运算符
var open = false
if !open {
print("打开")
}
var age = 20
var heiget = 170
var weight = 160
if (age > 18 && age < 30 && heiget > 165) || weight < 160 {
print("合格")
}
区间
闭区间:包含区间的所有值 a...b 例如:1...5 ->(1,2,3,4,5)
半闭区间:包含头不包含尾 a..<b 例如:1..<5 ->(1,2,3,4)
注意:区间只能用于整数,写小数会出问题
应用场景:遍历,数组等
for i in 1...5 {
print(i)
}
for i in 1..<5 {
print(i)
}
数组的基本使用
数组定义
// 有值数组
var arr1 = [1,2,3]
var arr2: Array = [1,2,3]
var arr3: Array<Int> = [1,2,3]
var arr4: [Int] = [1,2,3]
// 空数组
var arr5 = []
var arr6 = [Int]()
var arr7 = Array<Int>()
// 可变数组
var arr8 = []
// 不可变数组
let arr9 = []
数组的操作
01 获取长度
var arr12 = [1,2,3]
print(arr12.count) // 3
02 判断是否为空
var arr13 = [1,2,3]
print(arr13.isEmpty) // false
03 检索数组内部元素
var arr14 = [1,2,3]
print(arr14[0])
print(arr14[2])
print(arr14.first)
print(arr14.last)
print(arr14.minElement())
print(arr14.maxElement())
04 追加元素
var arr15: Array<Any> = [1,2,3]
arr15 .append(4)
arr15 .append("a")
print(arr15) // [1, 2, 3, 4, "a"]
05 插入元素
var arr17 = [1,2,3]
arr17.insert(4, atIndex: 0)
print(arr17) // [4, 1, 2, 3]
06 更新元素
var arr18 = [1,2,3]
arr18[1] = 9
print(arr18) // [1, 9, 3]
07 删除元素
var arr19 = [1,2,3]
arr19.removeAtIndex(0)
print(arr19)
var arr20 = [1,2,3]
arr20.removeLast()
print(arr20)
var arr21 = [1,2,3]
arr21.removeFirst()
print(arr21)
var arr22 = [1,2,3]
arr22.removeAll()
print(arr22)
var arr23 = [1,2,3]
arr23.removeAll(keepCapacity: false) // 是否保持容量,如果是true,即使删除了容量依然存在,容量是2的倍数
print(arr23)
print(arr23.capacity)
// 注意:如果数组是一个不可变数组,不能更新、插入、删除
数组其他操作
Range 范围
var arr24 = [1,2,3]
arr24.removeRange(Range(1..<2))
print(arr24) // [1,3]
var arr25 = [1,2,3]
arr25.removeRange(Range(0...0))
print(arr25) // [2,3]
var range = 0...5
var range1: Range<Int> = 0...5
var range2: Range<Int> = 0..<5
print(range) // 0..<6
print(range1) // 0..<6
print(range2) // 0..<5
数组的批量操作
var arr = [1,2,3]
arr.replaceRange(1..<2, with: [99,98,97,96])
print(arr) // [1, 99, 98, 97, 96, 3]
遍历
var arr1 = [1,2,3]
for i in 0 ..< arr1.count {
print(arr1[i])
}
for number in arr1 {
print(number)
}
var arr2 = [1,2,3]
for number in arr2[0..<3] {
print(number)
}
字典
字典的定义
// 注意:key一定是可以hash的(String,Int,Float,Double,Bool),value没有要求
var dict = ["name":"Eric","age":28]
print(dict) // ["age": 28, "name": Eric]
var dict1: Dictionary = ["name":"Larry","age":26]
print(dict1) // ["age": 26, "name": Larry]
// key必须是String类型,value任意
var dict2: Dictionary<String,AnyObject> = ["name":"Vivian","age":24]
print(dict2) // ["age": 24, "name": "Vivian"]
// key必须是String类型,value任意
var dict3: [String:AnyObject] = ["name":"Vivian","age":24]
var dict4: [String:AnyObject] = Dictionary(dictionaryLiteral:("name","Owen"),("age",30))
print(dict4)
// 可变字典
var dict5 = [:]
// 不可变字典
let dict6 = [:]
字典操作
01.获取
var dict7 = ["name":"Eric","age":28]
print(dict7["name"])
02.修改
dict7["name"] = "Brouth"
print(dict7)
dict7.updateValue("Lucy", forKey: "name")
print(dict7)
03.更新
// updateValue返回一个可选类型,如果字典中不存在需要更新的key,那么返回nil,如果存在,返回原始值
var dict8 = ["name":"Vivian","age":24]
if let original = dict8.updateValue("Marry", forKey: "name") {
print(dict8["name"])
}
print(dict8)
04.添加
var dict9 = ["name":"Eric","age":28]
dict9["weight"] = 130
05.删除
var dict10 = ["name":"Eric","age":28]
dict10.removeValueForKey("age")
// 注意:removeValueForKey() 返回一个可选类型,如果字典中不存在需要删除的key,那么返回nil并且不会执行任何操作,如果存在则删除key对应的值,并且返回被删除的值
var dict11 = ["name":"Eric","age":28]
if let orignal = dict11.removeValueForKey("name") {
print(dict11)
print(orignal)
}
06.遍历字典
var dict12 = ["name":"Eric","age":28,"sex":"male","height":170.5]
// 取出所有的key和value
for (key,value) in dict12 {
print("key = \(key) value = \(value)")
}
// 取出所有的key
for key in dict12.keys {
print(key)
}
// 取出所有的value
for value in dict12.values {
print(value)
}
if
if 条件表达式 {指令}
if 条件表达式 {指令} else {指令}
- 1.if后面的圆括号可以省略
- 2.只能以Bool作为条件语句
- 3.如果只有一条指令,if后面的大括号不可以省略
var age1: Int = 10
var age2: Int = 8
var max: Int?
if age1 > age2 {
max = age1
}
print(max) // 10
if age1 > age2 {
max = age1
} else {
max = age2
}
print(max) // 10
while循环
- 1.while后面的圆括号可以省略
- 2.只能bool作为条件语句
- 3.如果只有一条条件语句,while后面的大括号不可以省略
while i <= 10 {
i = i+1
sum = i
print("\(sum)")
}
do while 循环
格式:do while (循环保持条件) {执行的语句}
Swift 2.0之后变为repeat while, do用于捕捉异常
- 1.while后面的圆括号可以省略
- 2.只能bool作为条件语句
- 3.如果只有一条条件语句,while后面的大括号不可以省略
var j:Int = 0
var sum1:Int = 0
repeat {
j = j + 1
sum1 = j
print(sum1)
} while (j <= 10)
repeat {
j = j + 1
sum1 = j
print(sum1)
} while j <= 10
for循环
格式1: for (初始化表达式;循环保持条件;循环后表达式) {需要执行的语句} // swift3.0弃用
格式2: for in
- 1.for后面的圆括号可以省略
- 2.只能Bool作为条件语句
- 3.for后面的三个参数都可以省略,如果省略循环保持语句,那么默认为真
var sum: Int = 0
for i in 0..<10 {
sum += i
print(i)
print(sum)
}
for dict in ["name":"Vivian","age":18] {
print(dict)
}
for (key,value) in ["name":"Lucy","age":19] {
print("\(key) = \(value)")
}
break-continue
- break: 跳出循环,无论循环保持条件是否还为真都不会再执行循环
- continue: 跳出本次循环,如果循环保持条件还为真会继续执行循环
var array:Array<Int> = [1,3,5,8,9]
for num in array {
if num == 8 {
print("找到幸运数字-\(num)")
break
}
print("没有找到幸运数字-\(num)")
}
var arr: Array<Int> = [1,3,5,8,9]
var count:Int = 0
for num in arr {
if num % 2 != 0 {
print("\(num)-不能被2整除")
continue
}
print("\(num)-能被2整除")
}
Switch
格式: switch(需要匹配的值) case 匹配的值: 需要执行的语句 break
- 不可以穿透
- 可以不写break
var rank = "A"
switch rank {
case "A": // 相当于if
print("优")
case "B": // 相当于else if
print("良")
case "C": // 相当于else if
print("中")
case "D": // 相当于else if
print("差")
default: // 相当于else
print("没有评级")
}
可以这样写
var rank1 = "A"
switch rank {
case "A","B": // 相当于if
print("优")
case "C","D": // 相当于else if
print("中")
default: // 相当于else
print("没有评级")
}
函数定义
函数:完成某个特定任务的代码块,给代码块起一个合适的名称称为函数名称。以后需要执行代码块只需要利用函数名称调用即可。好比每个人都有一个名字,叫名字就能找到对应的人
格式:func 函数名称(参数名:参数类型,参数名:参数类型…) -> 函数返回值 {函数实现部分}
无参无返回值
func say() -> Void {
print("hello")
}
有参无返回值
func sayWithName(name:String) {
print("hello \(name)")
}
sayWithName("word")
func sayWithName1(name:String, age:Int) {
print("hello \(name) my age is \(age)")
}
sayWithName1("Eric", age: 25)
无参有返回值
func info() -> String {
return "name = Larry, age = 26"
}
info()
有参有返回值
func info(name:String,age:Int) -> String {
return "name is \(name), age is \(age)"
}
print(info("Owen",age:30))
闭包
函数是闭包的一种
类似于OC语言的block
闭包表达式(匿名函数) – 能够捕获上下文的值
语法:
in 关键字的目的是便于区分返回值和执行语句
闭包表达式的类型和函数的类型一样,是参数加上返回值,也就是in之前的部分
{
(参数) -> 返回值类型 in
执行语句
}
完整写法:
let say:(String) -> Void = {
(name: String) -> Void in
print("hi \(name)")
}
say("Mazy")
没有返回值写法
let say2:(String) -> Void = {
(name: String) in
print("hi \(name)")
}
say2("Lerry")
// 简写
let say2:(String) = {
(name: String) in
print("hi \(name)")
}
say2("Lerry")
没有参数没有返回值写法
let say3:() -> Void = {
print("hello world")
}
say3()
枚举
// 格式:
enum Method {
case 枚举值
}
enum Method {
// case Add
// case Sub
// case Mul
// case Div
// 可以连在一起写
case Add,Sub,Mul,Div
}
利用switch匹配枚举值
// 注意:如果case中包含了所有的值,可以不写default。如果case中没有包含枚举中的所有的值,必须写default
switch (Method.Add) {
case Method.Add:
print("加")
case Method.Sub:
print("减")
case Method.Mul:
print("乘")
case Method.Div:
print("除")
}
原始值
OC中枚举的本质就是整数,所以OC中的枚举是有原始值的,默认是从0开始的
而swift值的枚举值默认是没有原始值的,但是可以在定义时告诉系统让枚举有原始值
enum Method: 枚举的原始值类型 {
case 枚举值
}
enum Method1: Int {
// 可以连在一起写
case Add,Sub,Mul,Div
}
// 和OC的枚举一样,也可以指定原始值,后面的值默认+1
enum Method2: Int {
// 可以连在一起写
case Add = 5,Sub,Mul,Div
}
// swift 中的枚举除了可以指定整形以外还可以指定其他类型,但是如果指定了其他类型,必须给所有的枚举值赋值,因为不能自动递增
enum Method3: Double {
case Add = 5.0,Sub = 8.0,Mul = 9.0,Div = 10.0
}
结构体
结构体是用于封装不同或相同类型的数据的,swift中的结构体是一种类型,可以定义属性和方法(甚至构造方法和析构方法等)
格式:
struct 结构体名称 {
结构体属性和方法
}
struct Rect {
var width: Double = 0.0
var height:Double = 0.0
}
懒加载
格式:
lazy var 变量: 类型 = { 创建变量代码 }()
lazy var demoView: UIView = {
let view = UIView(frame: CGRectMake(10, 10, 100, 100))
view.backgroundColor = UIColor.redColor()
return view
}()
懒加载的写法本质上是定义并执行一个闭包