****1.常量和变量****
- let定义常量,一经赋值不允许再修改
- var 定义变量,赋值之后仍然可以修改
* 定义常量 let/变量 var
* 格式:let/var 变量名:类型 = 值
*提示:Swift提供了自动推导,如果使用默认的数据类型,':'类型 可以省略
* 格式:let/var 变量名=值,变量类型会根据右侧的结果'自动推导'
* 定义常量并且直接设置数值
let x: Int = 10
* 常量数值一经设置,不能修改,以下代码会报错
x = 30
* 使用: 类型
,仅仅只定义类型,而没有设置数值
let y: Int
* 常量有一次设置数值的机会,以下代码没有问题,因为y
还没有被设置数值
y = 10
* 一旦设置了数值之后,则不能再次修改,以下代码会报错,因为y
已经被设置了数值
y = 50
print(x + y)
* 变量设置数值之后,可以继续修改数值
var z: Int
z = 100
z = 200
print(x + y + z)
2.自定推导 - Swift能够根据右边的代码,推导出变量的准确类型
- 通常在开发时,不需要指定变量的类型
- 如果要指定变量,可以在变量名后使用':',让后跟上变量的类型
重要技巧:Option+Click可以查看变量的类型
没有隐式转换!
======== - Swift对数据类型要求异常严格
- 任何时候,都不会做隐式转换
如果要对不同类型的数据进行计算,必须要显示的转换
注意:Int & Double 都是结构体,而不是基本数据类型
整数默认的类型是Int
let x:Int = 200
小数的默认类型是Double
let y:Double = 10.5
不同类型之间不能直接计算
print(x + Int(y))
print(Double(x) + y)
let & var的选择
- 应该尽量选择常量,只有在必须修改时,才需要修改var
- 在Xcode 7.0 中,如果没有修改变量,Xcode会提示修改let
****Optional可选项****
- Swift是Swift的一大特色,也是Swift初学者最容易困惑的问题
- 定义变量时,如果指定是可选的,表示该变量可以有一个指定的类型,也可以是nil
- 定义变量时,在类型后面添加一个?,表示该变量是可选的
- 变量可选项的默认值是nil
- 常量可选性没有默认值,主要用于在构造函数中给常量设置初始值
// Optional 可能有两个值 (None / Some)
// 格式(1. 自动推导):var 变量名: Optional = 值
let x: Optional = 20
// 格式(2. 指定类型):var 变量
let y: Optional<Int> = 30
// 格式(3. 简化格式):var 变量名: 类型? = 值
let z: Int? = 10
// 可选值在参与计算前,必须`解包 unwarping`
// 只有`解包(unwrap)`后才能参与计算
// 在变量后添加一个 `!`,可以强行解包
// `?` 是用于定义的
// `!` 是用于解包的,程序员要对每一个 `!` 负责
print(x! + y! + z!)
- 如果Optional值是nil,不允许参与计算
- 只有 解包(unwrap)后才能参与计算
- 在变量后添加一个!,可以强行解包
注意:必须要确保解包后的值不是nil,否则会报错
===========================
// 常量可选项必须要设置初始值
let x: Int? //= 20
x = 20
// 变量可选项默认值是 nil
var y: Int? //= 10
y = 20
// unexpectedly found nil while unwrapping an Optional value
// 在对可选项解包时发现 nil,会报错!
if y == nil {
print("y值为 nil")
} else {
print(x! + y!)
}
常见错误
翻译
在对可选项[解包]是发现nil
****??运算符****
-
??运算符可以用于判断 变量/常量 的数组是nil,如果是则使用后面的值代替
-
在使用Swift开发时,?? 能够简化代码的编写
// 常量可选项必须要设置初始值 var x: Int? //= 20 // x = 30 // 变量可选项默认值是 nil var y: Int? //= 10 y = 20 print((x ?? 0) + (y ?? 0))
注意:?? 的优先级低,在使用时,应该注意使用()
var str: String? = "老王"
// 注意 `??` 的优先级低,在使用时,应该注意使用 `()`
print((str ?? "无名") + " 你好")
print(str ?? "无名" + " 你好")
****控制流****
if
-
Swift中没有C语言的非零即真的概念
-
在逻辑判断时必须显示地指明具体的判断条件 true/false
-
if语句条件的()可以省略
-
但是{}不能省略
let num = 200 if num < 10 { print("比 10 小") } else if num > 100 { print("比 100 大") } else { print("10 ~ 100 之间的数字") }
****三目运算符****
-
Swift中的三目运算保持了和OC一致的风格
x > 20 ? print("大了") : print("小了")/** `()` 表示执行 */ x > 20 ? print("真的大了") : ()
适当的运用三木,能够让代码写的更加简洁
****可选项判断****
-
由于可选项的内容可能为nil,而一旦为nil则不允许参与计算
-
因此在实际开发中,经常需要判断可选项的内容是否为nil
****单个可选项的判断****
let url = NSURL(string: "http://www.baidu.com")//: 方法1: 强行解包 - 缺陷,如果 url 为空,运行时会崩溃 let request = NSURLRequest(URL: url!) //: 方法2: 首先判断 - 代码中仍然需要使用 `!` 强行解包 if url != nil { let request = NSURLRequest(URL: url!) } //: 方法3: 使用 `if let`,这种方式,表明一旦进入 if 分 支,u 就不在是可选项 if let u = url where u.host == "www.baidu.com" { let request = NSURLRequest(URL: u) }
****可选项条件判断****
//: 1> 初学 swift 一不小心就会让 if 的嵌套层次很深,让代码变得很丑陋
if let u = url {
if u.host == "www.baidu.com" {
let request = NSURLRequest(URL: u)
}
}
//: 2> 使用 where 关键字,
if let u = url where u.host == "www.baidu.com" {
let request = NSURLRequest(URL: u)
}
- 小结
- if let 不能与使用 && || 等条件判断
- 如果要增加条件,可以使用 where子句
- 注意:where 子句没有智能提示
****多个可选项判断****
//: 3> 可以使用 `,` 同时判断多个可选项是否为空
let oName: String? = "张三"
let oNo: Int? = 100
if let name = oName {
if let no = oNo {
print("姓名:" + name + " 学号: " + String(no))
}
}
if let name = oName, let no = oNo {
print("姓名:" + name + " 学号: " + String(no))
}
判断之后对变量需要修改
let oName: String? = "张三"
let oNum: Int? = 18
if var name = oName, num = oNum {
name = "李四"
num = 1
print(name, num)
}
****guard****
- guard 是与 if let 相反的语法,Swift 2.0 推出的
let oName: String? = "张三"
let oNum: Int? = 18
guard let name = oName else {
print("name 为空")
return
}
guard let num = oNum else {
print("num 为空")
return
}
// 代码执行至此,name & num 都是有值的
print(name)
print(num)
- 在程序编写时,条件检测之后的代码相对是比较复杂的
- 使用 guard 的好处
-能够判断每一个值
-在真正的代码逻辑部分,省略了一层嵌套
****switch****
-
switch 不在局限于整数
-
switch 可以针对任意数据类型进行判断
-
不再需要break
-
每一个case后面必须有可以执行的语句
-
要保证处理所有可能的情况,不然编译器直接报错,不处理的条件放在default分之中
-
每一个case中定义的变量仅在当前case中有效,而OC中需要使用{}
let score = "优"
switch score { case "优": let name = "学生" print(name + "80~100分") case "良": print("70~80分") case "中": print("60~70分") case "差": print("不及格") default: break }
-
switch中同样能够赋值和使用 where子句
let point = CGPoint(x: 10, y: 10)
switch point {
case let p where p.x == 0 && p.y == 0:
print("中心点")
case let p where p.x == 0:
print("Y轴")
case let p where p.y == 0:
print("X轴")
case let p where abs(p.x) == abs(p.y):
print("对角线")
default:
print("其他")
} -
如果只希望进行条件判断,赋值部分可以省略
switch score {
case _ where score > 80: print("优")
case _ where score > 60: print("及格")
default: print("其他")
}
****循环**** -
OC风格的循环
var sum = 0
for var i = 0; i < 10; i++ {
sum += i
}
print(sum) -
for-in,0..<10 表示从0到9
sum = 0
for i in 0..<10 {
sum += i
}
print(sum) -
范围0...10表示从0到10
sum = 0
for i in 0...10 {
sum += i
}
print(sum)
注意:..< 和 ... 用于定义 Range 类型,左右都不要添加空格
格式: for 变量 in 范围 { // 代码 }
for _ in 0...10 {
print("hello")
}
****字符串****
在 Swift 中绝大多数的情况下,推荐使用 String 类型
- String 是一个结构体,性能更高
- String 目前具有了绝大多数 NSString 的功能
- String 支持直接遍历
- NSString 是一个 OC 对象,性能略差
- Swift 提供了 String 和 NSString 之间的无缝转换
****字符串演练****
-
遍历字符串中的字符
for s in str.characters {
print(s)
} -
字符串长度
let str = "hello世界"// 返回字符串转换成对应编码的字节数 // 一个中文在 UTF8 字符集中占 3 个字节 print(str.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)) // 返回字符个数 - 字符串长度 print(str.characters.count)
-
字符串拼接
-
直接在""中使用 (变量名) 的方式可以快速拼接字符串
let name = "老王"
let age = 18
let point = CGPoint(x: 100, y: 200)
print("\(name) \(age) \(point)")
我和我的小伙伴再也不要考虑 stringWithFormat 了 :D
- 可选项的拼接
- 如果变量是可选项,拼接的结果中会有 Optional
- 为了应对强行解包存在的风险,苹果提供了 ?? 操作符
- ?? 操作符用于检测可选项是否为 nil
- 如果不是 nil,使用当前值
- 如果是 nil,使用后面的值替代
let str1 = "Hello"
let str2 = "World"
let i: Int? = 32
str = "(i ?? 0) 个 " + str1 + " " + str2
- 格式化字符串
-
在实际开发中,如果需要指定字符串格式,可以使用String(format:...) 的方式
let h = 8 let m = 23 let s = 9 let timeString = String(format: "%02d:%02d:%02d", arguments: [h, m, s]) let timeStr = String(format: "%02d:%02d:%02d", h, m, s)
-
****String & Range的结合****
-
在 Swift 中,String 和 Range连用时,语法结构比较复杂
-
如果不习惯 Swift 的语法,可以将字符串转换成 NSString 再处理
let helloString = "我们一起飞" (helloString as NSString).substringWithRange(NSMakeRange(2, 3))
-
使用 Range 的写法
// advancedBy(正数) 向右增加索引值 // advancedBy(负数) 向左减少索引值 let startIndex = str.startIndex.advancedBy(1) let endIndex = str.endIndex.advancedBy(-1) let subString3 = str.substringWithRange(startIndex.. <endIndex) print(subString3)
-
集合
数组 -
数组使用 [] 定义,这一点与 OC 相同
//: [Int]
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] -
遍历
let array1 = ["老王", "老李"]// 通过下标遍历数组 for i in 0..<array1.count { print(array1[i]) } // 顺序遍历数组 for s in array1 { print(s) } // 遍历同时获取下标 for s in array1.enumerate() { print("\(s.index) \(s.element)") } // 遍历同时获取下标方法2 for (i, e) in array1.enumerate() { print("\(i) \(e)") } // 倒序遍历数组 for s in array1.reverse() { print(s) } // 倒序同时获取下标 for e in array1.reverse().enumerate() { print(e) }
-
可变&不可变
-
let 定义不可变数组
-
var 定义可变数组
let array = ["zhangsan", "lisi"]
//: 不能向不可变数组中追加内容
//array.append("wangwu")
var array1 = ["zhangsan", "lisi"]//: 向可变数组中追加内容 array1.append("wangle")
-
数组的类型
-
如果初始化时,所有内容类型一致,则数组中保存的是该类型的内容
-
如果初始化时,所有内容类型不一致,择数组中保存的是 NSObject
// array1 仅允许追加 String 类型的值 //array1.append(18) var array2 = ["zhangsan", 18] // 在 Swift 中,数字可以直接添加到集合,不需要再转换成 `NSNumber` array2.append(100) // 如果向 数组添加 `CG` 结构体,需要使用 `NSValue` 转换 array2.append(NSValue(CGPoint: CGPoint(x: 10, y: 10)))
-
-
数组的定义和实例化
-
数组的合并
-
必须是相同类型的数组才能够合并
-
开发中,通常数组中保存的对象类型都是一样的
array3 += array1// 必须是相同类型的数组才能够合并,以下两句代码都是不允许的 //array3 += array2 //array2 += array3
-
-
数组的删除
//: 删除指定位置的元素
array3.removeAtIndex(3)
//: 清空数组
array3.removeAll() -
内存分配
-
如果向数组中追加元素,超过了容量,会直接在现有容量基础上 * 2
var array: [String] = [String]() for i in 0..<9 { array.append("\(i) - hello") print("\(array) \(array.capacity)") }
-
****字典****
-定义
-同样适用[]定义字典
-
let不可变字典
-
var可变字典
-[String:NSObject]是最常用的字典类型//: [String : NSObject] 是最常用的字典类型
var dict = ["name": "zhangsan", "age": 18] -
赋值
- 赋值直接dict[key] = value格式
-
如果key不存在,会设置新值
-
如果key存在,会覆盖现有值
//: * 如果 key 不存在,会设置新值 dict["title"] = "boss" //: * 如果 key 存在,会覆盖现有值 dict["name"] = "lisi" dict
-
删除一个KEY
dict.removeValueForKey("age") -
遍历
-
k,v可以随便写
-
前面的是key
-
后面的是value
for d in dict { print("\(d.0) \(d.1)") } // 遍历 for (k, v) in dict { print("\(k) ~~~ \(v)") }
-
-
合并字典
-
如果可以不存在,会建立新值,否则会覆盖现有值
//: 合并字典
var dict1 = String: NSObject
dict1["nickname"] = "大老虎"
dict1["age"] = 100//: 如果 key 不存在,会建立新值,否则会覆盖现有值 for (k, v) in dict1 { dict[k] = v } print(dict)
-
网友评论