最近在读Swity by Tutorials这本书.想写写笔记来加深下对某些知识的理解.这是其中的第一篇 :)
Swift2.0新特性中最有代表性的有几个方面:
- 控制流语句中使用guard、repeat、do、defer
- 新的异常处理
- 协议扩展
- API检查
-
其他
<h3 id="1">新的控制流语句</h3>
- repeat使用.
用repeat/while来替代do/while:
var myAge:Int = 23
repeat {
myAge--
print(myAge)
} while (myAge>18)
当myAge小于等于18时,这段代码就会停止.
- guard的使用.
顾名思义,就是用来保护你的程序在特殊情况下也照样能运行或执行某些操作.其实就是在不符合某个条件时做出的另一种方法执行,上面那个例子可以改写为:
var myAge:Int = 23
repeat {
myAge--
print(myAge)
guard myAge > 20 else {
print("I am so young!")
continue
}
print("I am a young lady!")
} while (myAge>18)
当myAge小于等于20时就会打印I am so young(可惜我现在已经是young lady了:)
- defer的使用
当某些条件不满足而提前结束{...}里面的内容时,可以用defer来保证程序走出}时会执行某些操作.比如你在打开某些文件时遇到特殊情况而退出而忘掉关闭文件,可以使用defer来保证每次都关闭文件.
<h3 id="2">异常处理</h3>
假设解析JSON时候抛出异常:
protocol JSONParsable {
static func parse(json: [String: AnyObject]) throws -> Self
}
首先我们来定义个错误类型:
enum ParseError: ErrorType {
case MissingAttribute(message: String)
}
当解析的内容不为string类型时会抛出错误:
struct Person: JSONParsable {
let firstName: String
let lastName: String
static func parse(json: [String : AnyObject]) throws -> Person {
guard let firstName = json["first_name"] as? String else {
let message = "Expected first_name String"
throw ParseError.MissingAttribute(message: message)
}
guard let lastName = json["last_name"] as? String else {
let message = "Expected last_name String"
throw ParseError.MissingAttribute(message: message)
}
return Person(firstName: firstName, lastName: lastName)
}
}
可以用try/do/catch来检查错误类型:
do {
let person = try Person.parse(["foo": "bar"])
} catch ParseError.MissingAttribute(let message) {
print(message)
} catch {
print("Unexpected ErrorType")
}
现在可以给自己添加个名字了:
let myName = try! Person.parse(["first_name": "Girl",
"last_name": "iOS"])
<h3 id="3">协议扩展</h3>
可以对协议进行属性和方法的扩展.
首先定义个错误类型:
enum StringValidationError: ErrorType, CustomStringConvertible {
case MustStartWith(set: NSCharacterSet, description: String)
var description: String {
let errorString: String
switch self {
case .MustStartWith(_, let description):
errorString = "Must start with \(description)."
}
return errorString
}
}
定义个协议:
protocol StringValidationRule {
func validate(string: String) throws -> Bool
var errorType: StringValidationError { get }
}
protocol StringValidator {
var validationRules: [StringValidationRule] { get }
func validate(string: String) -> (valid: Bool, errors: [StringValidationError])
}
extension StringValidator {
func validate(string: String) -> (valid: Bool, errors:[StringValidationError]) {
var errors = [StringValidationError]()
for rule in validationRules {
do {
try rule.validate(string)
} catch let error as StringValidationError {
errors.append(error)
} catch let error {
fatalError("Unexpected error type: \(error)")
}
}
return (valid: errors.isEmpty, errors:errors)
}
}
可以测试下:
let letterSet = NSCharacterSet.letterCharacterSet()
let startsWithRule = StartsWithCharacterStringValidationRule(characterSet: letterSet, description: "letter")
do {
try startsWithRule.validate("foo")
try startsWithRule.validate("123")
} catch let error {
print(error)
}
其中foo会输出true.而123会输出Must start with letter
<h3 id="4">API检查</h3>
guard #available(iOS 9.0, *) else {return}
<h3 id="5">其他</h3>
后续补充 :)