1.我感覺Swift2.0最大改進就是減少金字塔寫法(就是那種if里面再套一個if然后再套一個if很丑的代碼),對于Swift1.2中的很多optional都進行確定值,使用guard和if let 可以減少一些那種金字塔的寫法。
1).使用guard
guard a > 10 else{ return }
2).使用傳統(tǒng)的if
if a > 10{ }
2.對于什么時候使用guard什么時候使用if (statement == nil)什么時候使用if let 的一些個人理解:
if let mobil = teleField.text{}
//這里進行不為空的操作
guard let mobilePhone = teleField.textelse{return}
//這里進行不為空的操作
guard對于if let的優(yōu)勢是:不用在大括號里面進行代碼的書寫,這樣就少了一層金字塔。因為guard的語法里面,只有當條件為假的時候才會去執(zhí)行大括號里面的內容,否則執(zhí)行大括號以外的內容。
if let 對于guard的優(yōu)勢在于:雖然guard可以將代碼寫在大括號以外,return和throw對于內存消耗相對于來說是最頂級的,而且這樣看起來代碼很長的一串。
對于這些還是得看自己寫代碼的習慣,這只是記錄一下我的習慣而已
3.枚舉和錯誤處理:
如果只是需要簡單的錯誤處理,完全沒有把這個ErrorTypeEnum搞得這么復雜,我這么做的原因是可以很清楚地知道錯誤類型,錯誤的描述,以及把Domain也包含進來,這樣可以便于管理
1).我定義了一個ErrorEnum來處理網絡請求可能出現(xiàn)的不同的情況
public enum NetWorkError:String{
case DATA_TYPE_ERROR = "數據類型錯誤!(Data type error)"
case STATUS_CODE_ERROR = "狀態(tài)碼錯誤!(Status code error)"
case MESSAGE_CODE_ERROR = "解析失敗時出現(xiàn)錯誤!(Message code error)"
case DATA_CODE_ERROR = "解析狀態(tài)數據時出現(xiàn)錯誤!(Data code error)"
case REQUEST_CODE_ERROR = "請求錯誤!(Request code error)"
static var Domain:String{
return "DataErrorDomain"
}
var code:Int{
switch self{
case .DATA_TYPE_ERROR:
return 10001
case .STATUS_CODE_ERROR:
return 10002
case .MESSAGE_CODE_ERROR:
return 10003
case .DATA_CODE_ERROR:
return 10004
case .REQUEST_CODE_ERROR:
return 10005
}
}
var description:String{
return self.rawValue
}
}
2).現(xiàn)在需要使用extension給
NetworkError添加錯誤處理,代碼如下:
extension NetWorkError:ErrorType{ }
3).使用ErrorType
這是一段我項目中的邏輯處理的函數
private func filter_dataForThrows(results:AnyObject!)throws -> AnyObject?{
guard let dataDic = results as? [String:AnyObject] else{
throw NetWorkError.DATA_TYPE_ERROR
}
if let notice = dataDic["notice_message"] as? String{
self.notice = notice
}
guard let status = dataDic["code"] as? Int else{
throw NetWorkError.STATUS_CODE_ERROR
}
switch status{
case 0:
if let cur_data = dataDic["data"] {
return cur_data
}else{
throw NetWorkError.DATA_CODE_ERROR
}
default:
throw NetWorkError.MESSAGE_CODE_ERROR
}
}
4).捕獲錯誤
我使用do catch來捕獲錯誤
do{
let _ = try filter_dataForThrows(results)
}catch let error{
if let cur_error = error as? NetWorkError{ print(cur_error.description) }
}
在這里我就可以很清楚的知道到底是哪里出了問題。
當然你可以直接只使用do,而不使用catch來捕獲錯誤。
do{
let result = try? self.filter_dataForThrows(results)
}
4.發(fā)現(xiàn)一個關于函數的語法糖吧
1).先看看正常的函數的可變參數語法:
函數聲明:
func variablePar(students:String...){
//這里students不能聲明為inout類型
students.forEach{ print($0) }
}
函數調用:
variablePar("zhangsan","lisi","wanger")
2).我發(fā)現(xiàn)的語法糖
我發(fā)現(xiàn)這個是在自學python的時候里面的可變參數的書寫形式,然我嘗試在Swift中實現(xiàn),出乎我的意料還真的可以這么寫,可以給一個參數提供一個默認值,從而達到不需要輸入這個參數的目的
函數聲明:
func defaultfunc(name:String,age:Int = 18){
}
函數調用:
defaultfunc("zhangsan")//第一種調用方法
defaultfunc("zhangsan", age: 19)//第二種調用方法
在python中,必選參數在前,默認參數在后,否則Python的解釋器會報錯(思考一下為什么默認參數不能放在必選參數前面)報錯:SyntaxError: non-default argument follows default argument,但是這個約束在Swift中并不會出現(xiàn)
5.生成器Generator
對于Swift序列和生成器的介紹的文章,可以在初探 Swift Sequences 和 Generators查看,我闡述一下我在學習Python的生成器和Swift生成器理解上的異同。
1).Swift中的生成器和序列的關系
在GeneratorType</code>和<code>SequenceType協(xié)議和文章初探 Swift Sequences 和 Generators來說一下我對他們的理解。
Generator類://這其實就是一個求斐波拉契數列(Fibonacci)的生成器
class FibonacciGenerator : GeneratorType {
var last = (0,1)
var endAt:Int
var lastIteration = 0
init(end:Int){
endAt = end
}
func next() -> Int?{
guard lastIteration<endAt else {
return nil
}
lastIteration++
let next = last.0
last = (last.1,last.0+last.1)
return next
}
}
他有一個next()函數這是為了生成下一個元素,遍歷到最后他會生成nil。
Sequence類://記?。哼@是一個序列,就好像Array一樣,你可以通過Array()來轉變?yōu)锳rray類型
class FibonacciSequence : SequenceType {
var endAt:Int
init(end:Int){
endAt = end
}
func generate() -> FibonacciGenerator{
return FibonacciGenerator(end: endAt)
}
}
其中的generate()函數就是生成上訴的生成器,然后你可以使用foreach,map,flatmap,reduce等等函數,不是很好描述,粗暴的描述就是:你可以把他轉換為其他類型的序列。
就像是在該文章中所說真的沒有必要你沒用一次就自己去創(chuàng)建一個Generator類,你可以直接使用AnyGenerator<Element>,他同時遵循了GeneratorType和SequenceType協(xié)議,下面是apple文檔中的舉例:
var x = 7
let g = anyGenerator { x < 15 ? x++ : nil }
let a = Array(g) // [ 7, 8, 9, 10, 11, 12, 13, 14 ]
生成了序列g然后通過g初始化了一個數組a。