变量与常量
Swift使用var声明变量,let声明常量。
var myVariable = 42 myVariable = 50 let myConstant = 42 //myConstant不能修改
类型推导
Swift支持类型推导(Type Inference),所以上面的代码不需指定类型,如果需要指定类型:
var str: String = "Swift" var str = "Swift" //自动推断类型为String
Swift的变量一旦声明了,就不能修改类型了,上面的例子中str只能是字符串类型,之后无论如何赋值都不能修改其类型。
所以我们说类型往往可以省略,但有些地方还是不能省略。特别是在集合类型上面,例如一个本来想放NSObject的字典,因为初始化用的字符串,就被推断成一个完全都是字符串的字典了。
有一个奇葩的地方,Swift 可以用任意Unicode字符当做变量名,也就是说,中文,图释,都是可以的。
var 中文 = "swift" var ? = "haha"
字符串String
注意这里生成的String,并不是NSString。他甚至都不是一个Object,我们可以在定义里面看到:
struct String { init() }
String和CFString一样,他是一个Struct! 不过String可以和NSString互相替代,而且API通用。
字符串笔记:
1.特殊字符 空字符\0,反斜杠\,制表符\t,换行符\n,回车符\r,双引号\”和单引号\’ 单字节Unicode字符,\xnn,其中nn是两个十六进制数 双字节Unicode字符,\unnnn,其中nnnn是四个十六进制数 四字节Unicode字符,\Unnnnnnnn,其中nnnnnnnn是八个十六进制数 2. 字符串不是指针,而是实际的值 在Swift中,一个String类型就是一个实际的值,当把String a 赋值给 String b或者把String a 传递给函数参数,实际相当于创建了一个相等的新值,而不是仅仅像指针那样指向过去。 var str5: String = "4" var str6 = str5 str5 = "5" println(str5) //输出5 println(str6) //输出4 3. 用属性 isEmpty 检查一个字符串是否为空 4. 用全局函数 countElements 计算字符串中字符的数量 5.字符串相等:当两个字符串包含的字符完全相同时,被判断为相等 == 6. hasPrefix 和 hasSuffix var str = "ssssdhjjaska" if str.hasPrefix("ssss") { println("str have prefix ssss") } 7. uppercaseString 和 lowercaseString
数组和字典
Swift使用[]操作符声明数组(Array)和字典(Dictionary):
var shoppingList = ["catfish", "water", "tulips", "blue paint"] shoppingList[1] = "bottle of water" var occupations = [ "Malcolm": "Captain", "Kaylee": "Mechanic", ] occupations["Jayne"] = "Public Relations" // 一般使用初始化器(initializer)语法创建空数组和空字典: let emptyArray = String[]() let emptyDictionary = Dictionary<String, Float>() // 如果类型信息已知,则可以使用[]声明空数组,使用[:]声明空字典。
Array和String一样,也是结构体。不过,Array不具有NSArray的API特性。需要显示转换成NSArray才可以调用其方法。
枚举
通过循环枚举,即
30 while flag {enum(arr)} 31 for a in arr {} 32 for var i=1;i<13;++i {} 33 for i in 1..10 {}
遍历数组
for (index, value) in enumerate(emptyArray) {
println("Item \(index): \(value)")
}
遍历字典
for (key, value) in dic {
println("\(key): \(value)")
}
获取字典的keys和values
let keys = Array(dic.keys)
let values = Array(dic.values)
控制流
Swift的条件语句包含if和switch,循环语句包含for-in、for、while和do-while,循环/判断条件不需要括号,但循环/判断体(body)必需括号:
let individualScores = [75, 43, 103, 87, 12] var teamScore = 0 for score in individualScores { if score > 50 { teamScore += 3 } else { teamScore += 1 } }
单路分支
在 if 语句中,条件必须是一个布尔表达式
77 if blablabla { 78 } 79 else{ 80 } 注意:这里的大括号不可以省略。 多路分支 81 switch num 82 { 83 case 1: 84 85 case 2: 86 87 default:
}
注意:不再需要写break,且default必须有!且必须所有条件都要覆盖到,一般情况下都会有default,但是若在enum中使用,就可以用case搞定了。
对于case来说,不仅可以写 case 1, case 2, 还可以写 case 1, 2, 3, 4, 甚至 case, 1, 2, 3, 4, 7..10
可空类型
结合if和let,可以方便的处理可空变量(nullable variable)。对于空值,需要在类型声明后添加?显式标明该类型可空。
var optionalString: String? = "Hello" optionalString == nil var optionalName: String? = "John Appleseed" var gretting = "Hello!" if let name = optionalName { gretting = "Hello, \(name)" }
? 表示的是:Optional。写法如下:
var possibleValue: Int? = animalLegs["xiaohaha"]
1 if possibleValue {
2 println("Notnil")
3 }
4 else {
5 println("111")
6 }
!的作用就是突破Optional,拿到内部值 62 if possibleValue { 63 let value = possibleValue! 64 println("xiaohaha has \(value) legs") 65 } 66 else { 67 println("> <") 68 } 不过这里,有个简练的写法,更漂亮优雅。 69 if let value = possibleValue 70 { 71 println("xiaohaha has \(value) legs") 72 } 73 else 74 { 75 println("> <") 76 }
//如果变量的可选值是 nil,条件会判断为 false,大括号中的代码会被跳过。如果不是 nil,会 将值赋给 let 后面的常量,这样代码块中就可以使用这个值了。
其他循环
for-in除了遍历数组也可以用来遍历字典:
let interestingNumbers = [ "Prime": [2, 3, 5, 7, 11, 13], "Fibonacci": [1, 1, 2, 3, 5, 8], "Square": [1, 4, 9, 16, 25], ] var largest = 0 for (kind, numbers) in interestingNumbers { for number in numbers { if number > largest { largest = number } } } largest
while循环和do-while循环:
var n = 2 while n < 100 { n = n * 2 } n var m = 2 do { m = m * 2 } while m < 100 m
Swift支持传统的for循环,此外也可以通过结合..(生成一个区间)和for-in实现同样的逻辑。
var firstForLoop = 0 for i in 0..3 { firstForLoop += i } firstForLoop var secondForLoop = 0 for var i = 0; i < 3; ++i { secondForLoop += 1 } secondForLoop
闭包
1.闭包表达式语法 { (parameters) -> return type in statements } 2.闭包和类的强引用 当将一个闭包赋值给一个类实例的属性,并且闭包体捕获这个实例时,也可能存在一个强引用循环。捕获实例是因为闭包体访问了实例的属性,就像self.someProperty,或者调用了实例的方法,就像self.someMethod()。不管哪种情况,这都造成闭包捕获self,造成强引用循环。
3.闭包之Sort函数
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
// Sort函数
func backwards(s1: String, s2: String) -> Bool { return s1 > s2 }
var reversed = sort(names, backwards)
// 闭包:-表达式语法
reversed = sort(names, { (s1: String, s2: String) -> Bool in return s1 > s2 } )
// 闭包:-根据上下文推断类型
reversed = sort(names, { s1, s2 in return s1 > s2 } )
// 闭包:-单行表达式闭包可以省略 return
reversed = sort(names, { s1, s2 in s1 > s2 } )
// 闭包:参数名简写
reversed = sort(names, { $0 > $1 } )
// 闭包:-运算符函数
reversed = sort(names, >)
//闭包: Trailing 闭包
reversed = sort(names) { $0 > $1 }
4.闭包之map函数
1. Swift 的 Array 类型有一个 map 方法,其获取一个闭包表达式作为其唯一参数。数组中的每一个元素调用一次该闭包函数,并返回该元素所映射的值(也可以是不同类型的值)。
2. let digitNames = [ 0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four",5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"]
let numbers = [16, 58, 510]
let strings = numbers.map {
(var number) -> String in
var output = ""
while number > 0 { output = digitNames[number % 10]! + output
number /= 10 }
return output
}
// 字典 digitNames 下标后跟着一个叹号 (!),因为字典下标返回一个可选值 (optional value),表明即使该 key不存在也不会查找失败。 在上例中,它保证了 number % 10 可以总是作为一个 digitNames 字典的有效下标 key。 因此叹号可以用于强展开 (force-unwrap) 存储在可选下标项中的 String 类型值。