您的位置:首页 > 移动开发 > Swift

Swift 基础语法

2016-04-02 22:42 471 查看
一、变量和常量

定义

let
定义常量,一经赋值不允许再修改

var
定义变量,赋值之后仍然可以修改

//: # 常量
//: 定义常量并且直接设置数值
let x = 20
//: 常量数值一经设置,不能修改,以下代码会报错
// x = 30

//: 使用 `: 类型`,仅仅只定义类型,而没有设置数值
let x1: Int
//: 常量有一次设置数值的机会,以下代码没有问题,因为 x1 还没有被设置数值
x1 = 30
//: 一旦设置了数值之后,则不能再次修改,以下代码会报错,因为 x1 已经被设置了数值
// x1 = 50

//: # 变量
//: 变量设置数值之后,可以继续修改数值
var y = 200
y = 300

自动推导

Swift能够根据右边的代码,推导出变量的准确类型

通常在开发时,不需要指定变量的类型

如果要指定变量,可以在变量名后使用:,然后跟上变量的类型


重要技巧:Option + Click 可以查看变量的类型





没有隐式转换!!!

Swift 对数据类型要求异常严格

任何时候,都不会做隐式转换


如果要对不同类型的数据进行计算,必须要显式的转换


let x2 = 100
let y2 = 10.5

let num1 = Double(x2) + y2
let num2 = x2 + Int(y2)

let & var 的选择

应该尽量先选择常量,只有在必须修改时,才需要修改为
var


在 Xcode 7.0 中,如果没有修改变量,Xcode 会提示修改为
let


二、Optional 可选类型

Optional
是 Swift 的一大特色,也是 Swift 初学者最容易困惑的问题

定义变量时,如果指定是
可选的
,表示该变量
可以有一个指定类型的值,也可以是 nil


定义变量时,在类型后面添加一个
?
,表示该变量是可选的

变量可选项的默认值是
nil


常量可选项没有默认值,主要用于在构造函数中给常量设置初始数值

//: num 可以是一个整数,也可以是 nil,注意如果为 nil,不能参与计算
let num: Int? = 10


如果 Optional 值是
nil
,不允许参与计算

只有
解包(unwrap)
后才能参与计算

在变量后添加一个
!
,可以强行解包


注意:必须要确保解包后的值不是 nil,否则会报错


//: num 可以是一个整数,也可以是 nil,注意如果为 nil,不能参与计算
let num: Int? = 10
//: 如果 num 为 nil,使用 `!` 强行解包会报错
let r1 = num! + 100

//: 使用以下判断,当 num 为 nil 时,if 分支中的代码不会执行
if let n = num {
let r = n + 10
}

常见错误

unexpectedly found nil while unwrapping an Optional value


翻译

在[解包]一个可选值时发现 nil


??
运算符

??
运算符可以用于判断
变量/常量
的数值是否是
nil
,如果是则使用后面的值替代

在使用 Swift 开发时,
??
能够简化代码的编写

let num: Int? = nil

let r1 = (num ?? 0) + 10
print(r1)


[/code]

三、控制流

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 一致的风格

var a = 10
var b = 20
let c = a > b ? a : b
print(c)


适当地运用三目,能够让代码写得更加简洁


可选类型判断

由于可选类型的内容可能为
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("其他")
}


[/code]

四、for 循环

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)


省略下标

_
能够匹配任意类型

_
表示忽略对应位置的值

for _ in 0...10 {
print("hello")
}


[/code]

五、字符串


在 Swift 中绝大多数的情况下,推荐使用
String
类型



String 是一个结构体,性能更高

String 目前具有了绝大多数 NSString 的功能

String 支持直接遍历

NSString 是一个 OC 对象,性能略差

Swift 提供了
String
NSString
之间的无缝转换

字符串演练

遍历字符串中的字符

for s in str.characters {
print(s)
}


字符串长度

// 返回以字节为单位的字符串长度,一个中文占 3 个字节
let len1 = str.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
// 返回实际字符的个数
let len2 = str.characters.count
// 返回 utf8 编码长度
let len3 = str.utf8.count


字符串拼接

直接在 "" 中使用
\(变量名)
的方式可以快速拼接字符串

let str1 = "Hello"
let str2 = "World"
let i = 32
str = "\(i) 个 " + str1 + " " + str2


我和我的小伙伴再也不要考虑
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 的写法

let startIndex = helloString.startIndex.advancedBy(0)
let endIndex = helloString.endIndex.advancedBy(-1)

helloString.substringWithRange(startIndex..<endIndex)


[/code]

六、集合

数组

数组使用
[]
定义,这一点与 OC 相同

//: [Int]
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


遍历

for num in numbers {
print(num)
}


通过下标获取指定项内容

let num1 = numbers[0]
let num2 = numbers[1]


可变&不可变

let
定义不可变数组

var
定义可变数组

let array = ["zhangsan", "lisi"]
//: 不能向不可变数组中追加内容
//array.append("wangwu")
var array1 = ["zhangsan", "lisi"]

//: 向可变数组中追加内容
array1.append("wangwu")


数组的类型

如果初始化时,所有内容类型一致,择数组中保存的是该类型的内容

如果初始化时,所有内容类型不一致,择数组中保存的是
NSObject


//: array1 仅允许追加 String 类型的值
//array1.append(18)

var array2 = ["zhangsan", 18]
//: 在 Swift 中,数字可以直接添加到集合,不需要再转换成 `NSNumber`
array2.append(100)
//: 在 Swift 中,如果将结构体对象添加到集合,仍然需要转换成 `NSValue`
array2.append(NSValue(CGPoint: CGPoint(x: 10, y: 10)))


数组的定义和实例化

使用
:
可以只定义数组的类型

实例化之前不允许添加值

使用
[类型]()
可以实例化一个空的数组

var array3: [String]
//: 实例化之前不允许添加值
//array3.append("laowang")
//: 实例化一个空的数组
array3 = [String]()
array3.append("laowang")


数组的合并

必须是相同类型的数组才能够合并

开发中,通常数组中保存的对象类型都是一样的!

array3 += array1

//: 必须是相同类型的数组才能够合并,以下两句代码都是不允许的
//array3 += array2
//array2 += array3


数组的删除

//: 删除指定位置的元素
array3.removeAtIndex(3)
//: 清空数组
array3.removeAll()


内存分配

如果向数组中追加元素,超过了容量,会直接在现有容量基础上 * 2

var list = [Int]()

for i in 0...16 {
list.append(i)
print("添加 \(i) 容量 \(list.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


遍历

k
v
可以随便写

前面的是
key


后面的是
value


//: 遍历
for (k, v) in dict {
print("\(k) ~~~ \(v)")
}


合并字典

如果 key 不存在,会建立新值,否则会覆盖现有值

//: 合并字典
var dict1 = [String: NSObject]()
dict1["nickname"] = "大老虎"
dict1["age"] = 100

//: 如果 key 不存在,会建立新值,否则会覆盖现有值
for (k, v) in dict1 {
dict[k] = v
}
print(dict)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: