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

Swift Basic: Optionals,Collection - 再来点 Swift 基础知识

2015-01-11 15:33 465 查看
1 - Optionals

Optionals的设计初衷,应该是体会到了各种dreaded null pointer。

在playground中输入以下代码:

var str
println(str)
将会得到报错:Type annotation missing in pattern

这表明编译器不知道str的类型

于是将代码改写成:

var str: String
println(str)
又得到报错:Variable 'str' used before being initialized

Swift是不允许你在compile time使用一个未经初始化的变量的。

如果真的需要一个值为nil的对象,该怎么办呢?

如果将代码更改成:

var str: String = nil
println(str)
会得到报错:Type 'string' does not conform to protocol 'NilLiteralConvertible'

既然将变量申明成String类型,那它就必须是个string,nil的类型并不是String,so出现错误。

但如果真的需要使用一个nil值,那就可以使用optional。Optionals are a way of wrapping up the concept of "has a value(有值)" or "may have a value(可能有值)" into a language-wide feature.

(1)Declaring optionals

var str: String?
这里类型后添加的question mark,就表明出这个字符串是optional的。这里,可以把optional想象成一种独立的类型,所以变量str可以存入nil或者是一个String类型的实例。当把str初始化为nil时,其实就是没有显式地分配给str一个String实例。

如果将代码改成:

var str: String? = "Hi Loi!"
println(str)
可以在playground的侧边栏看到{Some “Hi Loi!”},包装wrapping就长这个样,字符串被包装,花括号{}和“Some”表明这是一个optional类型。

如果加一句代码:

var str: String? = "Hi Loi!"
println(str)
str = str.uppercaseString
就会得到报错:‘String?’ does not have a member named 'uppercaseString'

optional类型实际上是没有uppercaseString这个method的。

改写代码:

var str: String? = "Hi Loi!"
println(str)
if let unwrappedStr = str {
println("Unwrapped! \(unwrappedStr.lowercaseString) ")
}
通过这个if statement,str被拆包了,并且赋了一个新的常量unwrappedStr,在if语句中,如果现在str包装的是一个字符串的实例,那unwrappedStr就变成一个String类型的变量,if语句的条件就可以pass,println语句就可以执行。

如果把代码改写成:

var str: String?
println(str)
if let unwrappedStr = str {
println("Unwrapped! \(unwrappedStr.lowercaseString) ")
} else {
println("nil")
}

这时候optional str就被包装成了nil,if语句条件就无法pass了,else后面的语句就执行了。

(2)Forced unwrapping

如果能够确定optional有值,可以使用强制拆包。

但如果此时optional实际上是nil就会产生run time error,这样会造成app crash

改写代码:

var str: String?
println(str)
println("Force unwrapped \(str!.lowercaseString)") //Fetal Error


(3)Implicit unwrapping

var str: String! = "Hi Loi!"
(4)Optional chaining

Optional chaining is a concise way to work with optionals quickly without using if/let and a conditional block each time.

var isString: String? = "Hi loi"
let lowerCase = isString?.lowercaseString
在第一行声明一个optional的字符串isString,然后在第二行变量后的?就是optional chaining的开始。

在run time,先check一下optional的isString的内容是不是真的存在,如果isString里确实包含一个实例,那就执行表达式lowercaseString,如果isString是nil,那就返回nil。

2 - Collection

在Swift中,只有两种primitive collection类型:arrays和dictionaries

(1)Array

Arrays provide an ordered list of elements.

var array:[Int] = [1, 2, 3, 4, 5]
println(array[3])
array.append(6)
println(array)
array.extend(7...10)
(2)Dictionaries

Dictionaries provide a list of mappings between keys and values.

var dictionary = [1: "Dog", 2: "Cat"]
var dictionary2: [Int:String] = [1: "Yes", 2: "No"]
println(dictionary[2])
dictionary[3] = "Tiger"
println(dictionary)
dictionary[1] = nil
println(dictionary)
if let value = dictionary[1] {
println("\(value)")
} else {
println("No value")
}
3)References and copies

Dictionaries are copied when you assign them to new variables and constants, or when you pass them as parameters to functions.

var dictionaryA = [1: 1, 2: 4, 3: 9, 4: 16]
var dictionaryB = dictionaryA
println(dictionaryA)
println(dictionaryB)
dictionaryB[4] = nil
println(dictionaryA)
println(dictionaryB)


var arrayA = [1, 2, 3, 4, 5]
var arrayB = arrayA
println(arrayA)
println(arrayB)
//arrayB.removeAtIndex(0)
arrayB[0] = 10
println(arrayA)
println(arrayB)

(4)Constant collections

let constantArray = [1, 2, 3, 4, 5]
constantArray.append(6)
constantArray.removeAtIndex(0)
报错:

1. immutable value of type '[Int]' only has mutating members named 'append' 

2. immutable value of type '[Int]' only has mutating members named 'removeAtIndex'
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Apple Cocoa Touch Swift iOS