swift 2.2 语法 (上)
Posted 黑森林工作室
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swift 2.2 语法 (上)相关的知识,希望对你有一定的参考价值。
前言:
1.此文中的语法会根据Swift的升级变动而更新。
2.如果需要请移步 -> swift2.2 语法(中)、swift 2.2语法(下)
Swift与OC中常见的区别
导入框架
OC:
#import <UIKit> #import "AFNetWorking.h"
Swift:
import UIKit
定义标识符
OC:
int i = 0;
Swift:
// 不可变标识符 let i = 0 或 let i : Int = 0 // 可变标识符 var i = 0 或 var i : Int = 0
“;”号的使用
- OC:每个语句后都必须加上;以示结尾
- Swift:
1.如果在一行中只有一条语句,那么语句结束时 “;” 号可以省略
2.如果一行中有多条,那么需要以 “;” 进行分割
常量和变量
- 在定义一个标识符时,必须明确告诉编译器这个标识符是变量还是常量
- 常量,需要在定义最前面加上 ‘let’,定义后不可修改
- 变量,需要在定义最前面加上 ‘var’,定义后可以修改
- 格式:let/var 标识符名称 : 类型 = 10;
- 格式:let/var 标识符名称 : 类型 = 10;
import UIKit
// 定义一个常量
let a : Int = 0 // 或 let a = 0
// 因为常量不可修改,所以 a = 1 的是错误的写法
// 定义一个变量
var b : Int = 0 // 或 var b = 0
// 因为变量可以修改,所以来修改下变量
b = 1
常量使用注意
- 在开发中优先使用常量,只有发现该标识符需要修改时,再改成变量(保证数据更加安全)
- 常量本质:指向的内存地址不可修改,但通过内存地址找到对应的对象,就可以修改对象内部属性
// 创建一个常量指向UIView并修改内部属性 let view : UIView = UIView() // 设置尺寸 view.frame = CGRectMake(0, 0, 150, 150) // 设置背景颜色 = UIColor.greenColor() // 定义一个常量保存尺寸信息 let rect = CGRectMake(0, 0, 150, 150) // 定义一个变量指向UIView并切换到UIButton var tempView : UIView = UIView(frame: rect) // 设置背景颜色 tempView.backgroundColor = UIColor.redColor() // 切换变量指向的View tempView = UIButton(type: .Custom)
swift中数据类型
- 介绍
- Swift中的数据类型也有:整型/浮点型/对象类型/结构体类型等
- 整型
- 有符号
- Int8 : 有符号8位整型
- Int16 : 有符号16位整型
- Int32 : 有符号32位整型
- Int64 : 有符号64位整型
- Int : 和平台相关(默认,相当于OC的NSInteger)
- 无符号
- UInt8 : 无符号8位整型
- UInt16 : 无符号16位整型
- UInt32 : 无符号32位整型
- UInt64 : 无符号64位整型
- UInt : 和平台相关(常用,相当于OC的NSUInteger)(默认)
- 浮点型
- Float : 32位浮点型
- Double : 64浮点型(默认)
- 有符号
- 整型
- Swift中的数据类型也有:整型/浮点型/对象类型/结构体类型等
类型推导
- Swift是强类型语言
- Swift中任何一个标识符都有明确的类型
- 注意:
- Swift中在定义一个标识符时,有直接给该标识符进行赋值,那么标识符后面的类型可以省略(因为类型推导会自动根据后面赋值的类型推导出前面标识符的类型)
- 在Swift中可以通过option + 鼠标左键,可以查看某个标识符的类型
// 定义一个Int类型的常量
let a : Int = 15
// 因为有类型推导的特性,所以上面的语句可以简写为
let a = 15 // 编译器会自动根据右边值得类型判定数据类型
// 定义一个浮点类型的常量
let b : Double = 3.14
// 因为有类型推导的特性,所以上面的语句可以简写为
let b = 3.14 // 因为右边是浮点型数据,所以编译器会判定常量类型为浮点型
基本运算
- 在Swift中,不同类型的数据类型之间不能进行运算(因为Swift中没有隐式转换)
- 如果数据类型不一致,就需要转化数据类型,使类型一致
// 相同类型运算
let a = 15
let b = 20
// 求和
let sum = a + b
// 不同类型运算
let a = 30.0
let b = 15
// 转换类型
let tempA = Int(a)
// 求和
let sum = tempA + b
判断分支
介绍
- 判断分支指if/switch/三目运算符等判断语句
- 通过判断分支可以控制程序的执行顺序
if判断
- if后面的()可以省略掉
在Swift中,判断语句必须有明确的真假
- if后面的判断句没有非0(nil)即真概念
- if后面的判断句必须明确真假(Bool) –> true/false
let a = 15 if a > 11{ print(a) } // 因为Swift中,只有声明成可选类型,才能判断是否为空 let view : UIView? = UIView() if view != nil { view!.backgroundColor = UIColor.blueColor() }
三目运算符(和OC一样,没有别的区别)
let a = 15
let b = 20
var result = a > b ? a : b
print(result)
- guard(守卫)使用
- guard是Swift2.0新增的语法
- 它与if语句非常类似,设计的目的是提高程序的可读性
- guard语句必须跟上else,{}内必须跟上break/continue/return
/* 假设成绩为100分,60以下为不及格 */
// 定义一个常量
let a = 99
// 定义一个test函数,参数Int类型
func test(a : Int) {
guard a >= 60 else {
print("不及格")
return
}
print("优秀")
}
// 调用函数
test(a)
switch判断
- 介绍
- 苹果对Switch进行了大大的增强,使其拥有其他语言没有的特性
- 使用
- 基本用法和OC一样
- switch后面的()可以省略
- case后的break可以省略(默认会自动填补break)
let a = 0 switch a { case 0 : print("真") case 1 : print("假") default : print("其它") }
- 一个case判断中,可以判断多个值(值之间用 “,” 分隔)
let a = 0 switch a { case 0, 1 : print("真假") default : print("其它") }
- 如果希望出现case穿透,可以使用关键字fallthrough
let a = 0 switch a { case 0 : fallthrough case 1 : print("假") default : print("其它") }
- switch支持多种数据类型(包含浮点型、字符串类型)
switch支持区间判断
- 常见的区间
1.半开半闭区间:0..<10(表示0~9)
2.闭区间:0…10(表示0~10)
/* 假设成绩为100分 */ let a = 88 switch a { case 0..<60: print("不及格") case 60..<80: print("几个") case 80..<90: print("良好") case 90..<100: print("优秀") default: print("满分") }
- 常见的区间
- 介绍
循环
循环是开发中必不可少的,常见循环有:for/while/do…while
- for循环
- for后面的()可以省略
- for后面的()可以省略
// 传统写法 for var i = 0; i < 15; i++ { print(i) } // 区间循环 for i in 0..<15 { print(i) } for i in 0...15 { print(i) } // 特殊写法 // 有时候我们只需要循环语句内的操作,不需要i,那么i可以用_代替 for _ in 0..<15 { print("hello world") }
- while循环
- while的判断句必须有真假(没有非0即真概念)
- while后面的()可以省略
var a = 0 while a < 10 { a++ }
- do…while循环
- 使用repeat关键字代替了do
- 使用repeat关键字代替了do
let a = 0 repeat { print(a) a++ } while a < 20
- for循环
字符串
- OC和swift中字符串的区别
- OC中字符串类型为NSString,在swift中字符串类型为String
- OC中字符串用@“”包装,swift中字符串用“”包装
- 使用String原因
- String是一个结构体,性能较高;NSString是一个OC对象,性能较差
- String支持直接遍历
- swift提供了String和NSString间无缝转换
定义
- 不可变字符串
let str = "hello world"
- 可变字符串
var str = "hello world"
- 不可变字符串
使用
- 获取字符串长度
let count = str.characters.count
- 遍历字符串
var str = "hello world" for tmp in str.characters { }
- 字符串拼接
let str1 = "hello" let str2 = "world" let str = str1 + str2
- 字符串和其它数据类型拼接
let str1 = "xiao ming" let str2 = 23 let str = "\\(str1)今年\\(str2)岁"
字符串的格式化
- 如:时间
let min = 3 let time = String(format:"%02d", arguments:[min])
- 如:时间
字符串截取方式
- 常用方式:String转换成NSString后再截取(简便)
let myStr = "hello world" var subStr = (myStr as NSString).substringFromIndex(4) subStr = (myStr as NSString).substringToIndex(3) subStr = (myStr as NSString).substringWithRange(NSRange(location: 4, length: 5))
- 方式二:使用swift原生截取方式
// 定义一个String类型的常量str let str : String = "http://blog.csdn.net/yeshaojian" // 截取开始位置 let startIndex = str.startIndex.advancedBy(7) let head = str.substringFromIndex(startIndex) // 截取结束位置 let endIndex = str.endIndex.advancedBy(-11) let foot = str.substringToIndex(endIndex) // 截取中间网址 let range = Range(start: startIndex, end: endIndex) let middle = str.substringWithRange(range)
- 常用方式:String转换成NSString后再截取(简便)
- 获取字符串长度
数组
介绍
- 数组(Array)是一串
有序的由相同类型元素
构成的集合 - 数组中的集合元素是
有序
的,可以重复
出现 - swift中的数组
- swift数组是一个
泛型集合
,类型
是Array,
- swift数组是一个
- 数组(Array)是一串
初始化数组
数组分为可变数组和不可变数组
- 使用
let
修饰的数组是不可变数组 - 使用
var
修饰的数组是可变数组
// 在swift中任意类型一般不用NSObject而会使用AnyObject // 定义一个不可变数组(存储内容为AnyObject) let array : [AnyObject] = ["123", 15, ["se"]] // 定义一个可变数组,并初始化值 var arrayM : [String] = [String]()
注意:在swift中任意类型一般不用NSObject而会使用AnyObject
- 使用
声明数组的简便写法
// 声明可变数组 var arrayM2 : Array<String> // 或 var arrayM3 : [String] // 声明不可变数组 let array1 : Array<AnyObject> let array2 : [AnyObject]
注意:声明的数组需要初始化才能使用,数组类型一般都是在声明的同时进行初始化
- 对声明的数组进行初始化
// 初始化值 arrayM2 = ["1", "2", "3"] // 初识化后可追加值 arrayM2.append("隔壁老王") // 因为上面我们声明的array1是let(常量),所以初始化后不能追加元素(不能使用append追加元素) array1 = ["se", 234]
- 数组的增、删、改、查
// 定义一个可变数组 var arrayM : [AnyObject] = ["123", 15, 25, 35] // 添加数据 arrayM.append("隔壁老王") // 取值 arrayM[4] // 修改元素 arrayM[0] = "12" // 删除数组最前面的元素(这边填 2 就表示删除2次,所以执行完毕后 隔壁老李 和 "123" 会被删除) arrayM.removeFirst(2) // 删除数组最后面的元素 arrayM.removeLast() // 删除指定下标的元素(0 表示删除第一个元素) arrayM.removeAtIndex(0) // 删除所有元素 arrayM.removeAll()
- 数组的遍历
// 定义一个可变数组 var arrayM : [AnyObject] = ["123", 15, 25, 35, "隔壁老王"] // 方式一:遍历数组下标 for i in 0..<arrayM.count { print(i) } // 方式二:遍历数组内容 for name in arrayM { print(name) } // 方式三:设置数组遍历区间 for name in arrayM[0..<3] { print(name) } // 方式四(常用)遍历数组同时获取下标 for (i, name) in arrayM.enumerate() { print("\\(i)--\\(name)") }
- 数组合并
// 相同类型的数组才能合并 let array1 = ["123", "157", "12345", "234567", "15689123"] let array2 = ["1568648", "26879435", "1578715645"] let array3 = array1 + array2 // 一个数组最好不要存放多种类型数据 var arrayM1 = ["mms", 56, "隔壁老王", 37, "15689123"] var arrayM2 = [12, "哈哈哈哈", "1578715645"] var arrayM3 = arrayM1 + arrayM2
注意:只有相同类型的数组才能合并
字典
介绍
- 字典由键(key)集合和值(value)集合两部分构成
- 键集合不能有重复元素,而值集合可以重复,每一个键对应一个值
- 字典可以按照某个键来访问对应的元素
- swift字典类型为
Dictionary
,和数组一样死个`泛型集合“
初始化字典
swift的字典分为可变和不可变字典2种
- 使用
let
修饰的字典是不可变字典 - 使用
var
修饰的字典是可变字典
// 定义一个不可变字典 let dict = ["name" : "laoWang", "city" : "隔壁", "age" : 35] // 定义一个 var dictM : [String : AnyObject] = [String : AnyObject]()
注意:在swift中任意类型一般不用NSObject而会使用AnyObject
- 使用
- 声明字典
// 声明不可变字典 let dict1 : [Int : AnyObject] let dict2 : Dictionary<Int, AnyObject> // 声明可变字典 var dictM1 : [Int : AnyObject] var dictM2 : Dictionary<Int, AnyObject>
注意:和数组一样,声明的字典也需要初始化值后才可使用
- 声明的字典需要初始化才能使用,字典类型一般是在声明的同时进行初始化
// 初始化不可变字典值 dict1 = [0 : "aa", 1 : "bb", 2 : "cc"] dict2 = ["name" : "laoWang", "age" : 35] // 初始化可变字典值 dictM1 = ["name" : "laoWang", "age" : 35] dictM2 = [0 : "aa", 1 : "bb", 2 : "cc"]
- 字典的增删改查
// 添加Key为city value为gebi dictM1["city"] = "gebi" // 修改 dictM1["name"] = "laoLi" // 查询 dictM1["name"] // 删除 dictM1.removeValueForKey("city") // 删除所有元素 dictM1.removeAll()
- 字典遍历
// 方式一:遍历字典内所有值 for value in dictM1.values { print(value) } // 方式二:遍历字典中所有的键 for key in dictM1.keys { print(key) } // 方式三:遍历字典中键和值 for (key, value) in dictM1 { print("\\(key) : \\(value)") }
- 字典合并
// 字典合并 // 只有字典内容类型相同的字典才可合并 // 定义一个不可变字典(key:String类型 value:AnyObject类型) let dict1 : [String : AnyObject] = ["name" : "laoWang", "age" : 35] // 定义一个可变字典(key:String类型 value:AnyObject类型) var dictM2 : Dictionary<String, AnyObject> = ["city" : "gebi"] // 遍历dict1的key和value并合并(添加)到dictM2字典中 for (key, value) in dict1 { dictM2[key] = value } print(dictM2)
注意:只有字典内容类型相同的字典才可合并
元组
元组是Swift中特有的,OC中并没有相关类型
- 元组是一种数据结构,类似于数组或者字典
- 可以用于定义一组数据
- 多个值组合而成的复合值。元组中的值可以是任意类型,而且每一个元素的类型可以不同
- 组成元组类型的数据称为“元素”
定义元组
// 方法一:基本写法(格式:(元素,元素) 数据类型不限) let personInfo1 = ("老王", 35, 1.80, "laoWang") // 方法二:在上面方法的基础给元素定义名称 let personInfo2 = (name:"老王", age:35, height:1.80, EnglishName:"laoWang") // 方法三:先定义元素名,在设置值 let (name, age, height, EnglishName) = ("老王", 35, 1.80, "laoWang") // 方法四:明确有几个元素并且确定类型 var personInfo3 : (Int, String) = (0, "老王")
元组操作
// 通过下标或者别名读取值 personInfo1.0 personInfo2.name name
可选类型
可选类型作用:
- 在OC中,如果一个变量暂停不适用,可以赋值为0(基本属性类型)或赋值为空(对象类型)
- 在swift中,nil被定义为一个特殊的类型,因为和真是的类型不匹配是不能赋值的(强类型语言特性)
- 为了在开发中赋值为nil,毕竟很经常用到,所以推出了可选类型
- 可选类型的取值为:
- 空值
- 有值
可选类型定义
- 基本写法(不常用)
// 基本写法 let user : Optional<String> = nil
- 糖语法(推荐)
// 糖语法 let user : String? = nil
- 基本写法(不常用)
可选类型简单使用
// 可选类型使用
var user : String? = nil
// 给可选类型赋值(我们上面定义的可选类型为String类型,所以只能给他赋值String类型)
user = "laoWang"
// 可选类型取值(在可选类型内,只能通过强制解包来取出可选类型的真实类型)
// 强制解包方式一:
user!
// 需要注意的是,如果可选类型为nil(为空),强制取出其中的值(强制解包),会出错
// 强制解包方式二:
if user != nil {
print (user!)
}
// 为了在if语句里面方便使用user,我们可以定义一个可选绑定类型,这样也能达到严谨取值的效果(底层也是帮我们进行判断,有值就会解包)
if let userStr = user {
print (userStr)
}
注意:
1.如果可选类型为nil(为空),强制取出其中的值(强制解包),会出错,所以解包前需要进行判断
2.为了使用方便,解包会以可选绑定
的形式实现
- 可选类型重要性(让代码逻辑更加严谨)
// OC中,我们在定义一个包含中文的NSURL的时候是这样的
NSString *urlStr = @"http://www.xxxxx.com/中文/sie";
// 因为字符串中包含中文,所以需要对字符串进行UTF8编码转换,防止出现访问错误
NSString *str = [urlStr stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// 再将其包装成NSURL
NSURL *url = [NSURL URLWithString:str];
// 在swift中,如果字符串中包含中文,且我们没有对其进行处理,那么就会直接返回nil
// 也就是说,url可能有值也可能没值,这时候就需要用可选类型来接收
// 方法一:标准写法
let url : NSURL? = NSURL(string: "http://www.xxxxx.com/中文/sie")
// 方法二:利用类型推导
let url2 = NSURL(string: "http://www.xxxxx.com/中文/sie")
// 方法三:可选绑定
if let temp = url {
let request = NSURLRequest(URL: temp)
print (request)
}
类型转化
类型转化符号
- as:将示例转成某一类型
- as?:判断是否有值,有则转换,没有则不转换(推荐)
- as!:不判断是否有值,直接转换(不安全)
- is:用来判断一个示例是否是某一种类型
// 定义一个数组 let array : [AnyObject] = ["laoWang", 15, 18.9] // 取出数组中的第二个元素 let temp = array[1] // 判断第一个元素类型是否为字符串 if temp is String { print("true") } else { print("flase") } // 将objc转成真实类型 // 方式一:使用as?将AnyObject转成可选类型,通过判断可选类型是否有值,来决定是否转换成功 let age = temp as? Int print(age) // 方式二:使用as!将AnyObject转成真实类型,因为objc的真实类型为Int不是String,通过as!进行转换后,会直接报错 let age1 = temp as! String print(age1)
- as:将示例转成某一类型
以上是关于swift 2.2 语法 (上)的主要内容,如果未能解决你的问题,请参考以下文章
Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题