好记性不如烂笔头,边学边记,重点比较Swift跟Objective-C的区别。
1 数据类型
1.1 类型检查
类型检查Swift的一个特性,它可以根据你申明的变量/常量内容自动推断其数据类型。代码不再需要分号;结尾。
1.2 变量与常量
let 申明常量
var 申明变量
申明指定类型的变量/常量
let number: Int
number = 32
var string: String = "Knowhere"
1.3 字符串插值
let numberOfStoplights: Int = 4
var population: Int population = 5422
let townName: String = "Knowhere"
let townDescription = "\(townName) has a population of \(population) and \(numberOfStoplights) stoplights."
print(townDescription)
2 条件语句
2.1 if/else
if
var isTrue: Bool = true
if !isTrue {
print("真的是true")
}
if else
var population: Int = 5422
var message: String
var hasPostOffice: Bool = true
if population < 10000 {
message = "\(population) is a small town!"
if a > b {
a += b
}
}
else if population >= 10000 && population < 50000 {
message = "\(population) is a medium town!"
}
else {
message = "\(population) is pretty big!"
}
print(message)
2.2 三目运算符
a < b ? a : b
3 数
3.1 整数
有符号的整数类型即能表示正数又能表示负数。(Int、Int16等)
对应的无符号整型,用来表示大于等于0的整数。(UInt、UInt16等)
有符号整数和无符号整数的区别在于二进制层面最高(对于8整数来说是2^7 )表示的2的次幂是正数还是负数。
4 switch语句
分支自带break控制
var statusCode: Int = 404
var errorString: String
switch statusCode {
case 400:
errorString = "Bad request"
case 401:
errorString = "Unauthorized"
case 403:
errorString = "Forbidden"
case 404:
errorString = "Not found"
default:
errorString = "None"
}
switch分支可以有多个值
var statusCode: Int = 404
var errorString: String
switch statusCode {
case 400, 401, 403, 404:
errorString = "There was something wrong with the request."
fallthrough
default:
errorString += " Please review the request and try again."
}
switch分支可以用一个值、多个值或者区间值
var statusCode: Int = 404
var errorString: String = "The request failed with the error:"
switch statusCode {
case 100, 101:
errorString += " Informational, 1xx."
case 204:
errorString += " Successful but no content, 204."
case 300...307:
errorString += " Redirection, 3xx."
case 400...417:
errorString += " Client error, 4xx."
case 500...505:
errorString += " Server error, 5xx."
default:
errorString = "Unknown. Please review the request and try again."
}
值绑定
switch statusCode {
case 100, 101:
errorString += " Informational, 1xx." errorString += " Informational, \(statusCode)."
case 204:
errorString += " Successful but no content, 204."
case 300...307:
errorString += " Redirection, 3xx." errorString += " Redirection, \(statusCode)."
case 400...417:
errorString += " Client error, 4xx." errorString += " Client error, \(statusCode)."
case 500...505:
errorString += " Server error, 5xx." errorString += " Server error, \(statusCode)."
default:
errorString = "\(unknownCode) is not a known error code."
}
5 元组
var statusCode: Int = 418
var errorString: String = "The request failed with the error:"
let error = (statusCode, errorString)
//元组的元素
error.0
error.1
//给元组的元素起名
let error = (code: statusCode, error: errorString)
error.code
error.error
用元组做模式匹配
let firstErrorCode = 404
let secondErrorCode = 200
let errorCodes = (firstErrorCode, secondErrorCode)
switch errorCodes {
case (404, 404):
print("No items found.")
case (404, _):
print("First item not found.")
case (_, 404):
print("Second item not found.")
default:
print("All items found.")
}
6 循环
for循环
var myFirstInt: Int = 0
for i in 1...5 {
myFirstInt += 1
myFirstInt
print(myFirstInt)
}
//也可以用_代替i
for _ in 1...5 {
myFirstInt += 1
myFirstInt
print(myFirstInt)
}
where循环
var i = 1
while i < 6 {
if i == 3 {
print("找到3啦")
break
}
myFirstInt += 1
print(myFirstInt)
i += 1
}
repeat-while循环,也就是do-while
repeat {
print("Fire blasters!")
} while shields > 0
7 字符串
//拼接
let playground = "Hello, playground"
var mutablePlayground = "Hello, mutable playground"
mutablePlayground += "!"
//遍历
for c: Character in mutablePlayground.characters {
print("'\(c)'")
}
//找到第5个字符
let start = playground.startIndex
let end = playground.index(start, offsetBy: 4)
let fifthCharacter = playground[end] // "o"
//获取区间
let start = playground.startIndex
let end = playground.index(start, offsetBy: 4)
let fifthCharacter = playground[end] // "o"
let range = start...end
let firstFive = playground[range] // "Hello"
8 可空类型
Swift的可空类型让这门语言更加安全。一个可能为nil的实例应该被声明为可空类型。这意味着如果一个实例没有被声明为可空类型,它就不可能是nil。通过这种方式,编译器知道一个实例是否可能为nil。
var errorCodeString: String?
errorCodeString = "404"
9 数组
var可变,let不可变.
两个数组元素相同,但元素顺序不同点话,这两个数组不相等。
//指定类型
var bucketList: Array<String>
//使用类型推断,初始化
var bucketList = ["abc"]
//添加元素
bucketList.append("ddd")
//删除元素
bucketList.remove(at: 1)
//用下标寻找前三个目标
print(bucketList[0...2])
//用下标添加信息
bucketList[2] += "gf"
//替换元素
bucketList[0] = "aaaaa"
//用循环从一个数组添加元素到另一个数组
var newItems = ["Fly hot air balloon to Fiji", "Watch the Lord of the Rings trilogy in one day", "Go on a walkabout", "Scuba dive in the Great Blue Hole", "Find a triple rainbow" ]
for item in newItems {
bucketList.append(item)
}
//用+=替换
//+=运算符是把新元素的数组添加到现存目标清单的好办法
bucketList += newItems
10 字典
//4种创建方式,结果一样
var dict1: Dictionary<String, Double> = [:]
var dict2 = Dictionary<String, Double>()
var dict3: [String:Double] = [:]
var dict4 = [String:Double]()
var movieRatings = ["Donnie Darko": 4, "Chungking Express": 5, "Dark City": 4]
//统计个数
print("I have rated \(movieRatings.count) movies.")//3
//读取值
let darkoRating = movieRatings["Donnie Darko"]
//增加
movieRatings["abc"] = 5
//删除
movieRatings.removeValue(forKey: "abc")
//修改值
movieRatings["Dark City"] = 5
//updateValue(_:forKey:)方法也可以修改值,oldRating是旧值
let oldRating: Int? = movieRatings.updateValue(5, forKey: "Donnie Darko")
print(movieRatings22["Donnie Darko"]!)
//把一个键的值设为nil
movieRatings["Dark City"] = nil
//遍历字典
for (key, value) in movieRatings {
print("The movie \(key) was rated \(value).")
}
for movie in movieRatings.keys {
print("User has rated \(movie).")
}
//把键/值输入数组
let watchedMovies1 = Array(movieRatings.keys)
let watchedMovies2 = Array(movieRatings. values)
11 集合Set
集合石一组互不不相同的实例的无序组合。这个定义将其与数组区别开来,后者是有序的,并且可以容纳重复的值。比如说,数组可以有类似[2,2,2,2]的内容,但集合不行。
//创建
var groceryBag = Set<String>()
//添加元素
groceryBag.insert("Apples")
groceryBag.insert("Oranges")
groceryBag.insert("Pineapple")
//或者直接赋初值
var groceryBag = Set(["Apples", "Oranges", "Pineapple"])
//遍历
for food in groceryBag {
print(food)
}
Set类型提供了contains(_:)方法来查看其内部是否有某个特殊的元素
let hasBananas = groceryBag.contains("Bananas")
这段代码增加了一个新的Set常量来表示你朋友的食品袋,并且用union(:)方法把两集合合并起来。union(:)是Set类型的一个方法,接ԩ一个SequenceTypeԟ数,并返回一个新的Set实例。该实例包含了两个容器中去重后的元素。简单地说,你可以把字典集合传给union(_:)并得到一个包含合并后元素集合,不会有重复。
//并集
var groceryBag = Set(["Apples", "Oranges", "Pineapple"])
let friendsGroceryBag = Set(["Bananas", "Cereal", "Milk", "Oranges"])
let commonGroceryBag = groceryBag.union(friendsGroceryBag)
//交集
let roommatesGroceryBag = Set(["Apples", "Bananas", "Cereal", "Toothpaste"])
let itemsToReturn = commonGroceryBag.intersection(roommatesGroceryBag)
//检查集合的交集
let yourSecondBag = Set(["Berries", "Yogurt"])
let roommatesSecondBag = Set(["Grapes", "Honey"])
//没有交集,disjoint为真
let disjoint = yourSecondBag.isDisjoint(with: roommatesSecondBag)
12 函数
无参数函数
//定义无参数函数
func printGreeting() {
print("Hello, playground.")
}
//调用函数
printGreeting()
带参函数
//带参函数
func printPersonalGreeting(name: String, numerator: Double) {
print("Hello \(name), welcome to your playground. \(numerator)")
}
//调用带参函数
printPersonalGreeting(name: "Matt", numerator: 4.0)
外部参数
func printPersonalGreeting(to name: String) {
//内部用name
print("Hello \(name), welcome to your playground.")
}
//外部用to
printPersonalGreeting(to: "Matt")
变长参数
变长参数接受零个或更多输入值作为实参。函数只能有一个变长参数,而且一般应该是参数列表中的最后一个。参数值在函数内部以数组的形式可用。
func printPersonalGreetings(to names: String...) {
for name in names {
print("Hello \(name), welcome to the playground.")
}
}
printPersonalGreetings(to: "Alex","Chris","Drew","Pat")
in-out参数
var error = "The request failed:"
func appendErrorCode(_ code: Int, toErrorString errorString: inout String) {
if code == 400 {
errorString += " bad request."
}
}
appendErrorCode(400, toErrorString: error)
error
函数有返回值
参数后面添加-> 类型
func AAdivisionDescriptionFor(aa: Double, bb: Double, withPunctuation punctuation: String = ".") -> String {
return "\(aa) divided by \(bb) equals \(aa / bb)\(punctuation)"
}
print(AAdivisionDescriptionFor(aa: 9.0, bb: 3.0))
print(AAdivisionDescriptionFor(aa: 9.0, bb: 3.0, withPunctuation: "?"))
多个返回值,返回值为元组
func sortedEvenOddNumbers(_ numbers: [Int]) -> (evens: [Int], odds: [Int]) {
var evens = [Int]()
var odds = [Int]()
for number in numbers {
if number % 2 == 0 {
evens.append(number)
}
else {
odds.append(number)
}
}
return (evens, odds)
}
let aBunchOfNumbers = [10,1,4,3,57,43,84,27,156,111]
let theSortedNumbers = sortedEvenOddNumbers(aBunchOfNumbers)
print("The even numbers are: \(theSortedNumbers.evens); the odd numbers are: \(theSortedNumbers.odds)")
可返回空值
func grabMiddleName(fromFullName name: (String, String?, String)) -> String? {
return name.1
}
let middleName = grabMiddleName(fromFullName: ("Matt",nil,"Mathias"))
if let theName = middleName {
print(theName)
}
13 闭包
闭包 = 一个函数「或指向函数的指针」+ 该函数执行的外部的上下文变量「也就是自由变量」;OC中的Block即闭包。
etc…