Swift4.2_基础语法(下)

官方文档

  • 可选类型 (Optionals)

值可能不存在的情况下,你可以使用可选类型。 一个可选类型代表两种可能性:要么它有值(你可以通过解包来访问该值), 或者没有值。

Note: 在CObjective-C中不存在可选类型的概念。 在OC中和可选类型这个概念最类似的是: 一个对象要么返回确定的值要么返回nil,其中nil表示“对象不存在”。然而这种方法仅适用于对象,并不适用于结构体、C的基本类型以及枚举。 对于这些类型,OC方法通常返回一个特殊值(例如NSNotFound)来表示没有值。 这种机制假设了方法调用者知道存在一个特殊的值,而且会通过这个值来检测方法的结果。Swift的可选类型可以让你表示任意类型的值缺失,并不需要特殊值。
这有一个例子说明了如何使用可选类型来处理不存在的值。 SwiftInt类型有一个String类型的值转换成Int类型的初始化方法。 但是,并不是每个字符串都可以转换为Int类型。 字符串"123"可以转换为数值123,但字符串helloworld明显没有数字值可转换为Int

以下的示例使用这个初始化方法尝试将一个String转换为Int:

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
//  convertedNumber被转换为类型"Int?",即"可选类型Int"
  • Nil

通过赋值nil,你可以将一个可选类型设置为无值状态:

var serverResponseCode:Int? = 404
// serverResponseCode包含一个具体的Int值,即404
serverResponseCode = nil
// serverResponseCode现在不包含任何值

NOTE: nil不能和非可选类型的常量和变量一起使用。 如果你的代码中的常量或变量在某些情况下需要以没有值的状态运行,那你应该始终将其声明为可选类型。

如果你定义了一个可选类型的变量, 但是不设置默认值,那么该变量的值将自动设置为nil:

var surveyAnswer: String?
// surveyAnswer is automatically set to nil

NOTE: Swift中的nil不同于OC中的nil。 在OC中,nil是一个指向不存在的对象的指针。 在Swift中,nil不是指针, 它是一个不存在值的特定类型的。 任何数据类型的可选类型都可以设置为nil,而不仅仅是对象类型。

  • If语句和强制解包 (If Statements and Forced Unwrapping)

你可以通过使用if语句比较可选类型和nil,进而确定这个可选类型是否包含具体的值。你可以使用等于 运算符== 或 不等于 运算符!=执行比较。

如果一个可选类型有一个值,即它被认为是“不等于”nil

if convertedNumber != nil {
    print("convertedNumber contains some integer value.")
}
// Prints "convertedNumber contains some integer value."

一旦你确定可选类型确实有值,你可以通过在可选类型名称的末尾添加感叹号(!)来访问其包含的值。这个感叹号如同在宣称:“ 我知道这个可选类型肯定有值,请使用它。” 这被称为可选类型的强制解包:

if convertedNumber != nil {
    print("convertedNumber has an integer value of \(convertedNumber!).")
}
// Prints "convertedNumber has an integer value of 123."

NOTE:
使用 (!) 时,访问不存在值的可选类型会触发运行错误, 所以在使用(!) 强制解包前, 要始终确保可选类型包含了非空的值。

  • 可选绑定 (Optional Binding)

你可以使用可选绑定来确定可选类型是否包含值,如果这样做,你必须把这个绑定的值用作临时常量或变量。可选绑定可以与if-while 语句一起使用,以检查可选类型中的值,并作为这个操作的一部分将该值提取为常量或变量。if-while语句在控制流(Control Flow)中有更详细的描述。

if语句编写可选绑定如下所示:

if let constantName = someOptional {
    statements
}

你可以使用可选绑定重写 Optionals 部分的possibleNumber示例,而不是使用强制解包:

if let actualNumber = Int(possibleNumber) {
    print("The string \"\(possibleNumber)\" has an integer value of \(actualNumber)")
} else {
    print("The string \"\(possibleNumber)\" could not be converted to an integer")
}
// Prints "The string "123" has an integer value of 123"

你可以在单个if语句中按你的需求包含多个可选绑定和Boolean条件,并以逗号分隔。如果可选绑定中的任何值为nil或任何Boolean条件为false,则整个if语句的条件被认为是false。以下第二段if代码和第一段是等效的:

if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
    print("\(firstNumber) < \(secondNumber) < 100")
}
// Prints "4 < 42 < 100"

if let firstNumber = Int("4") {
    if let secondNumber = Int("42") {
        if firstNumber < secondNumber && secondNumber < 100 {
            print("\(firstNumber) < \(secondNumber) < 100")
        }
    }
}
// Prints "4 < 42 < 100"
  • 隐式解包可选类型 (Implicitly Unwrapped Optionals)
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // 要求加上!来解包
 
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // 不需要加上!也可以解包
  • 错误处理 (Error Handling)

你可以使用错误处理来应对你的程序在执行过程中可能遇到的错误。

与可选类型相反,错误处理可以通过值的存在或不存在来表示一个function的成功或失败,允许你确定error的根本原因,如有必要,它还能将error传送到程序的另一部分。

当方法遇到错误条件时,会抛出一个error。 该方法的调用者可以捕获错误并作出适当的响应。

func canThrowAnError() throws {
     //这个函数可能会抛出一个错误
}

一个函数通过在其声明中包含throws关键字来说明它可以抛出异常。 当你调用一个可以抛出异常的函数时,你可以在表达式中添加try 关键字。

Swift会自动将错误传送到当前作用域之外,直到被catch语句处理

do {
    try canThrowAnError()
    // no error was thrown
} catch {
    // an error was thrown
}

do语句创建一个新的包含范围,它允许将错误传送到一个或多个catch子句。
以下是一个示例,说明如何使用错误处理来响应不同的错误条件:

func makeASandwich() throws {
    // ...
}
do {
    try makeASandwich()
    eatASandwich()
} catch SandwichError.outOfCleanDishes {
    washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
    buyGroceries(ingredients)
}
  • 断言Assertions和先决条件Preconditions

断言和先决条件之间的区别在于被执行的时间点有所不同:断言仅在调试版本中执行,但在调试和发布版本中先决条件都会被执行。 在发布版本中,断言内的条件不再被执行。 这意味着你可以在开发过程中使用尽可能多地使用断言,因为这并不会影响发布版本的性能。

用断言进行调试:

通过从Swift标准库调用assert(_:_:file:line:)方法,你写下一个断言。 你将一段文字和一个结果为truefalse的表达式赋值给这个方法,如果表达式的结果为false,则显示这段文字。 例如:

let age = -3
assert(age >= 0, "A person's age can't be less than zero.")
// This assertion fails because -3 is not >= 0.

在这个例子中,如果age> = 0的值为true,那么代码继续执行,即age为正值。 如果age为负值,如上面的代码所示,age> = 0false,断言失败,终止应用程序。

你可以省略断言发布的文字——例如当它只是一个单调的重复条件。

assert(age >= 0)

如果代码已经检查了条件,则使用assertionFailure(_:file:line:)方法来标明断言失败了。 例如:

if age > 10 {
    print("You can ride the roller-coaster or the ferris wheel.")
} else if age > 0 {
    print("You can ride the ferris wheel.")
} else {
    assertionFailure("A person's age can't be less than zero.")
}

当条件有可能为false的时候使用先决条件,但是必须确保你的代码会继续执行。 例如,你可以使用先决条件来判断下标是否越界,或者检查方法是否接收到一个有效的值。

通过调用precondition(_:_:file:line:)方法你可以编写先决条件。 你需要给此方法赋值一个表达式,其计算结果为true或false,如果条件的结果为false,则显示一段文字(也是由你赋值)。 例如:

// In the implementation of a subscript...
precondition(index > 0, "Index must be greater than zero.")
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容