swift变量

1. swift的基本变量类型html

 swift 的变量类型和OC、C基本类似,int = 整形, double = 双精度浮点 , float = 单精度浮点, string = 字符串, bool = 布尔值,swift

swift中一行结束不须要使用 ; ,可是若是两句代码写到同一行,就须要用 ; 隔开api

2.swift属性声明数组

和OC不一样,swift的属性分为变量和常量,用let 声明常量,用var声明变量,常量的值不可更改。安全

属性注释服务器

  1. var welcomeMessage: String 

如上代码, : 表示的是属性类型,上面声明的是一个 String类型的变量,变量名是welcomeMessage 数据结构

welcomeMessage只能赋值为字符串。app

也能够定义多个相同类型的属性,中间用逗号隔开less

  1. var red, green, blue: Double

如上,定义了三个 Double类型的变量。ide

swift有变量类型推导,因此基本上不用定义类型,好比

      var text = 10   

这时text就是int类型的。

变量名能够包括任意字符,甚至Unicode,和汉语,常量和变量名称不能包含空白字符,数学符号,箭头,专用(或无效)Unicode代码点或线条和框图字符。也不能以数字开头,尽管数字可能包含在名字的其余地方。

一旦声明了某个类型的常量或变量,就不能再声明它的名字,或者改变它来存储不一样类型的值。你也不能把一个常量变成一个变量或一个常量变量。

 

打印函数为Print()

print(_:separator:terminator:)函数是一个全局函数,它将一个或多个值打印到适当的输出。例如,在Xcode中,该print(_:separator:terminator:)函数在Xcode的“控制台”窗格中输出其输出。separatorterminator参数都有默认值,因此当你调用这个函数,你能够忽略它们。默认状况下,函数经过添加换行符来终止打印的行。要打印一个没有换行符的值,传递一个空字符串做为终止符 - 例如print(someValue, terminator: "")

 

Swift使用字符串插值将常量或变量的名称做为占位符包含在较长的字符串中,并提示Swift将其替换为该常量或变量的当前值。用圆括号将名称包装起来,并在左括号以前用反斜杠进行转义:

  1. print("The current value of friendlyWelcome is \(friendlyWelcome)")
  2. // Prints "The current value of friendlyWelcome is Bonjour!"

注意

你能够用串插中使用的全部选项中描述字符串插值

注释

使用注释在代码中包含不可执行的文本,做为注释或提醒。在编译代码时,Swift编译器会忽略注释。

Swift中的注释与C中的注释很是类似。单行注释以两个正斜杠(//开头

  1. // This is a comment.

多行注释以正斜杠开始,后跟星号(/*),以星号结尾,后跟正斜杠(*/):

  1. /* This is also a comment
  2. but is written over multiple lines. */

与C中的多行注释不一样,Swift中的多行注释能够嵌套在其余多行注释中。您能够经过启动多行注释块,而后在第一个块内开始第二个多行注释来编写嵌套注释。而后关闭第二个块,而后关闭第一个块:

  1. /* This is the start of the first multiline comment.
  2. /* This is the second, nested multiline comment. */
  3. This is the end of the first multiline comment. */

嵌套的多行注释使您可以快速轻松地注释大量代码,即便代码已经包含多行注释。

分号

与许多其余语言不一样,Swift不须要;在代码中的每一个语句以后都写一个分号(),尽管若是你愿意的话能够这样作。可是,若是要在一行中编写多个单独的语句须要使用分号

  1. let cat = "🐱"; print(cat)
  2. // Prints "🐱"

整型

整数是没有小数部分的整数,如42-23整数有符号(正数,零或负数)或无符号数(正数或零)。

Swift提供了8,16,32和64位格式的有符号和无符号整数。这些整数遵循相似于C的命名约定,其中8位无符号整数是类型的UInt8,32位有符号整数是类型的Int32像Swift中的全部类型同样,这些整数类型都有大写的名字。

整数界限

你能够用它来访问每一个整数类型的最小值和最大值minmax特性:

  1. let minValue = UInt8.min // minValue is equal to 0, and is of type UInt8
  2. let maxValue = UInt8.max // maxValue is equal to 255, and is of type UInt8

这些属性的值是适当大小的数字类型(UInt8例如上面的示例中),所以能够在表达式中与其余相同类型的值一块儿使用。

诠释

在大多数状况下,您不须要选择要在代码中使用的特定大小的整数。Swift提供了一个额外的整数类型,Int它与当前平台的本地字大小大小相同:

  • 在一个32位平台上,Int尺寸与Int32

  • 在64位平台上,Int尺寸与Int64

除非须要使用特定大小的整数,不然请Int在代码中使用整数值。这有助于代码的一致性和互操做性。即便在32位平台上,Int也能够存储-2,147,483,648之间的任意值2,147,483,647,而且对于不少整数范围来讲足够大。

UINT

Swift还提供了一个无符号整数类型,UInt它的大小与当前平台的本地字大小相同:

  • 在一个32位平台上,UInt尺寸与UInt32

  • 在64位平台上,UInt尺寸与UInt64

注意

UInt仅在您特别须要与平台的本机字大小相同的无符号整数类型时才使用若是不是这种状况,Int即便要知道存储的值是非负的也是优选的。Int整数值的一导致用有助于代码的互操做性,避免了在不一样数字类型之间进行转换的须要,并匹配整数类型推断,如类型安全和类型推断中所述

浮点数字

浮点数是具备小数部分的数字,例如3.141590.1,和-273.15

浮点类型能够表示比整数类型更普遍的数值范围,而且能够存储比能够存储在数组中更大或更小的数字IntSwift提供了两个有符号的浮点数类型:

  • Double 表明一个64位的浮点数。

  • Float 表示一个32位的浮点数。

注意

Double具备至少15位十进制数的精度,而精度Float能够小至6位十进制数。要使用适当的浮点类型取决于您须要在代码中使用的值的性质和范围。在任何类型都适合的状况下,Double是首选。

类型安全和类型推断

Swift是一个类型安全的语言。类型安全的语言鼓励你清楚你的代码可使用的值的类型。若是你的代码的一部分须要一个String,你不能Int错误地经过它

由于Swift是类型安全的,因此它在编译代码时执行类型检查,并将任何不匹配的类型标记为错误。这使您可以在开发过程当中尽早捕获并修复错误。

类型检查有助于避免在使用不一样类型的值时发生错误。可是,这并不意味着你必须指定你声明的每一个常量和变量的类型。若是你不指定你须要的值的类型,Swift使用类型推断来计算出适当的类型。类型推断使编译器可以在编译代码时自动推断特定表达式的类型,只需检查您提供的值便可。

因为类型推理,与C或Objective-C等语言相比,Swift所需的类型声明要少得多。常量和变量仍然是明确的类型,可是不少指定类型的工做都是为你完成的。

当你用一个初始值声明一个常量或变量时,类型推断特别有用。这一般是经过在声明它的点处为常量或变量赋予一个文字值(或文字)来完成的。(A字面值是直接出如今源代码中,如一个值423.14159在下面的例子。)

例如,若是你将一个42新的常量赋值给一个新的常量,而没有说明它是什么类型的话,那么Swift推断你想让这个常量成为一个常量Int,由于你用一个看起来像一个整数的数字来初始化它:

  1. let meaningOfLife = 42
  2. // meaningOfLife is inferred to be of type Int

一样,若是你没有为浮点数指定一个类型,Swift会推断你想建立一个Double

  1. let pi = 3.14159
  2. // pi is inferred to be of type Double

当推断浮点数的类型时, Swift老是选择Double(而不是Float)。

若是在表达式中结合整数和浮点文字,Double将从上下文中推断出一种类型

  1. let anotherPi = 3 + 0.14159
  2. // anotherPi is also inferred to be of type Double

字面值3没有明确的类型自己,因此Double从浮点文字的存在推断出适当的输出类型做为加法的一部分。

数字文字

整数文字能够写成:

  • 一个十进制数,没有前缀

  • 一个二进制数字,带有0b前缀

  • 一个八进制数,有0o前缀

  • 一个十六进制数,有0x前缀

全部这些整数文字都有一个十进制值17

  1. let decimalInteger = 17
  2. let binaryInteger = 0b10001 // 17 in binary notation
  3. let octalInteger = 0o21 // 17 in octal notation
  4. let hexadecimalInteger = 0x11 // 17 in hexadecimal notation

浮点文字能够是十进制(不带前缀)或十六进制(带0x前缀)。它们必须在小数点的两侧始终有一个数字(或十六进制数字)。十进制浮点数也能够有一个可选的指数,用大写或小写表示e十六进制浮点数必须有一个指数,用大写或小写表示p

对于指数为的十进制数exp,基数乘以10 exp

  • 1.25e2意味着1.25 x 10 2,或125.0

  • 1.25e-2意味着1.25 x 10 -2,或者0.0125

对于指数为的十六进制数exp,基数乘以2 exp

  • 0xFp2指15 x 2 2,或60.0

  • 0xFp-2指的是15 x 2 -2,或者3.75

全部这些浮点文字都有十进制值12.1875

  1. let decimalDouble = 12.1875
  2. let exponentDouble = 1.21875e1
  3. let hexadecimalDouble = 0xC.3p0

数字文字能够包含额外的格式,以方便阅读。整数和浮点数均可以用额外的零填充,而且能够包含下划线来帮助提升可读性。这两种格式都不影响字面值的基础值:

  1. let paddedDouble = 000123.456
  2. let oneMillion = 1_000_000
  3. let justOverOneMillion = 1_000_000.000_000_1

数字类型转换

Int在代码中 使用全部通用整数常量和变量类型,即便它们已知是非负的。在平常状况下使用默认的整数类型意味着整型常量和变量能够在您的代码中当即互操做,而且将与整型文字值的推断类型相匹配。

仅当手头任务特别须要使用其余整数类型时,才能使用其余整数类型,这是由于来自外部源的显式大小的数据,或性能,内存使用状况或其余必要的优化。在这些状况下使用明确大小的类型有助于捕获任何意外的值溢出,并隐含地记录正在使用的数据的性质。

整数转换

能够存储在整数常量或变量中的数字范围对于每种数字类型都是不一样的。一个Int8常数或变量能够存储之间的数字-128127,而UInt8常数或变量能够存储之间的数字0255在编译代码时,不能将其放入常量或变量的大小的整数类型中会报告为错误:

  1. let cannotBeNegative: UInt8 = -1
  2. // UInt8 cannot store negative numbers, and so this will report an error
  3. let tooBig: Int8 = Int8.max + 1
  4. // Int8 cannot store a number larger than its maximum value,
  5. // and so this will also report an error

因为每种数字类型均可以存储不一样范围的值,所以您必须逐个选择数字类型转换。这种选择加入方法能够防止隐藏的转换错误,并有助于在代码中明确类型转换意图。

要将一个特定的号码类型转换为另外一个号码类型,您须要使用现有的值初始化一个所需类型的新号码。在下面的例子中,常量twoThousand是类型的UInt16,而常量one是类型的UInt8他们不能直接加在一块儿,由于他们不是同一类型的。相反,这个例子调用UInt16(one)建立一个新UInt16one,并用这个值代替原来的值:

  1. let twoThousand: UInt16 = 2_000
  2. let one: UInt8 = 1
  3. let twoThousandAndOne = twoThousand + UInt16(one)

由于添加的两边都是如今的类型UInt16,因此容许添加。输出常量(twoThousandAndOne)被推断为是类型的UInt16,由于它是两个UInt16的总和

SomeType(ofInitialValue)是调用Swift类型的初始值设定项并传入初始值的默认方式。在幕后,UInt16有一个接受一个UInt8的初始化器,因此这个初始化器被用来UInt16从现有的一个新UInt8你不能在这里传入任何类型,可是它必须是一个UInt16提供初始化的类型扩展示有类型以提供接受新类型(包括您本身的类型定义)的初始化方法在扩展中介绍

整数和浮点转换

整数和浮点数字类型之间的转换必须明确:

  1. let three = 3
  2. let pointOneFourOneFiveNine = 0.14159
  3. let pi = Double(three) + pointOneFourOneFiveNine
  4. // pi equals 3.14159, and is inferred to be of type Double

在这里,常量的值three被用来建立一个新的类型值Double,因此添加的两边是相同的类型。若是没有这个转换,不容许增长。

浮点到整数转换也必须明确。整数类型可使用DoubleFloat来初始化

  1. let integerPi = Int(pi)
  2. // integerPi equals 3, and is inferred to be of type Int

当用这种方式初始化一个新的整数值时,浮点值老是被截断的。这意味着4.75变成4-3.9变成-3

注意

数字常量和变量的组合规则与数字文字的规则不一样。字面值3能够直接添加到文字值0.14159,由于数字文字自己没有明确的类型。只有在编译器评估它们的时候才推断它们的类型。

类型别名

类型别名为现有类型定义了一个替代名称。您可使用typealias关键字定义类型别名

若是要经过上下文更合适的名称引用现有类型,例如在从外部源处理特定大小的数据时,类型别名颇有用:

  1. typealias AudioSample = UInt16

一旦你定义了一个类型别名,你能够在任何你可能使用原始名称的地方使用别名:

  1. var maxAmplitudeFound = AudioSample.min
  2. // maxAmplitudeFound is now 0

这里AudioSample被定义为一个别名UInt16由于它是一个别名,AudioSample.min实际调用的调用UInt16.min,它提供0maxAmplitudeFound变量的初始值

布尔

Swift有一个基本的布尔类型,叫作Bool布尔值被称为逻辑,由于它们只能是真或假。Swift提供了两个布尔常量值,true而且false

  1. let orangesAreOrange = true
  2. let turnipsAreDelicious = false

根据它们用布尔文字值初始化的事实推断了这些类型orangesAreOrangeturnipsAreDelicious已经被推断出来Bool正如IntDouble上面,你并不须要声明常量或变量Bool,若是将其设置为truefalse为您建立它们尽快。类型推断有助于使Swift代码在使用其余已知类型的值初始化常量或变量时更加简洁易读。

当您使用条件语句(如if语句)时,布尔值特别有用

  1. if turnipsAreDelicious {
  2. print("Mmm, tasty turnips!")
  3. } else {
  4. print("Eww, turnips are horrible.")
  5. }
  6. // Prints "Eww, turnips are horrible."

控制流程if中更详细地介绍了 诸如声明等条件语句

Swift的类型安全性能够防止非布尔值被替换Bool如下示例报告编译时错误:

  1. let i = 1
  2. if i {
  3. // this example will not compile, and will report an error
  4. }

可是,下面的替代示例是有效的:

  1. let i = 1
  2. if i == 1 {
  3. // this example will compile successfully
  4. }

i == 1比较 的结果是类型的Bool,因此这个第二个例子经过类型检查。比较像i == 1基本操做符中讨论

就像Swift中的其余类型安全例子同样,这种方法避免了意外错误,并确保特定代码段的意图老是清晰的。

元组

组将多个值组合为一个复合值。元组中的值能够是任何类型,没必要是彼此相同的类型。

在这个例子中,(404, "Not Found")是一个描述HTTP状态码的元组每当您请求网页时,HTTP状态码都是由Web服务器返回的特殊值。404 Not Found若是您请求不存在的网页,则会返回状态代码

  1. let http404Error = (404, "Not Found")
  2. // http404Error is of type (Int, String), and equals (404, "Not Found")

这个(404, "Not Found")元组将an Int和a 分组在一块儿String,为HTTP状态码提供了两个独立的值:一个数字和一我的类可读的描述。它能够被描述为“一个类型的元组(Int, String)”。

你能够从任何类型的排列中建立元组,而且能够包含尽量多的不一样类型。没有什么阻止你有型的元组(Int, Int, Int),或者(String, Bool),或者你确实须要的任何其余排列。

你能够一个元组的内容分解成单独的常量或变量,而后像往常同样访问:

  1. let (statusCode, statusMessage) = http404Error
  2. print("The status code is \(statusCode)")
  3. // Prints "The status code is 404"
  4. print("The status message is \(statusMessage)")
  5. // Prints "The status message is Not Found"

若是您只须要某些元组的值,则_在分解元组时,请使用下划线(忽略部分元组:

  1. let (justTheStatusCode, _) = http404Error
  2. print("The status code is \(justTheStatusCode)")
  3. // Prints "The status code is 404"

或者,使用从零开始的索引号访问元组中的各个元素值:

  1. print("The status code is \(http404Error.0)")
  2. // Prints "The status code is 404"
  3. print("The status message is \(http404Error.1)")
  4. // Prints "The status message is Not Found"

当定义元组时,能够将元组中的各个元素命名为:

  1. let http200Status = (statusCode: 200, description: "OK")

若是您将元素命名为元组,则可使用元素名称来访问这些元素的值:

  1. print("The status code is \(http200Status.statusCode)")
  2. // Prints "The status code is 200"
  3. print("The status message is \(http200Status.description)")
  4. // Prints "The status message is OK"

元组做为函数的返回值特别有用。尝试检索网页的函数可能会返回(Int, String)元组类型来描述页面检索的成功或失败。经过返回具备两个不一样类型的值的元组,每一个不一样类型的函数都提供了有关其结果的更多有用信息,而不是仅返回单个类型的单个值。有关更多信息,请参阅具备多个返回值的函数

注意

元组对于相关值的临时组是有用的。它们不适合建立复杂的数据结构。若是您的数据结构可能会持续超出临时范围,则将其建模为类或结构,而不是元组。有关更多信息,请参阅类和结构

选配

在价值可能不存在的状况下 使用可选项可选的表明两种可能性:要么有一个值,你能够解开可选的访问值,或者有没有价值可言。

注意

C或Objective-C中不存在可选项的概念。Objective-C中最接近的东西是nil从一个方法返回的能力,不然返回一个对象,nil意思是“缺乏一个有效的对象”。可是,这只适用于对象 - 它不适用于结构,基本C类型或枚举值。对于这些类型,Objective-C方法一般会返回一个特殊值(如NSNotFound)来指示缺乏值。这种方法假设方法的调用者知道有一个特殊的值来测试,并记得检查它。Swift的选项可让你指出没有任何类型的值,而不须要特殊的常量。

如下是如何使用可选项来应对价值缺失的一个例子。Swift的Int类型有一个初始化器,它试图将一个String值转换成一个Int值。可是,并非每一个字符串均可以转换成一个整数。该字符串"123"能够转换为数字值123,但字符串"hello, world"没有明显的数值转换。

下面的例子使用初始化器来尝试将a String转换为Int

  1. let possibleNumber = "123"
  2. let convertedNumber = Int(possibleNumber)
  3. // convertedNumber is inferred to be of type "Int?", or "optional Int"

由于初始化器可能失败,因此它返回一个可选的 Int,而不是一个Int可选Int是写成Int?,而不是Int问号表示它所包含的值是可选的,这意味着它可能包含一些 Int值,或者它可能根本不包含任何值(它不能包含任何其余的东西,好比Bool值或String值,它能够是一个Int,或者什么也不是。)

经过给可选变量赋予一个特殊值来设置一个可选变量nil

  1. var serverResponseCode: Int? = 404
  2. // serverResponseCode contains an actual Int value of 404
  3. serverResponseCode = nil
  4. // serverResponseCode now contains no value

注意

你不能使用nilnonoptional常量和变量。若是代码中的某个常量或变量须要在某些条件下没有值的状况下工做,则始终将其声明为适当类型的可选值。

若是您定义了一个可选变量而不提供默认值,则会自动nil为您设置该变量

  1. var surveyAnswer: String?
  2. // surveyAnswer is automatically set to nil

注意

Swift nilnilObjective-C 不同在Objective-C中,nil是一个指向不存在对象的指针。在Swift中,nil不是一个指针,而是缺乏某种类型的值。选配的任何类型能够设置为nil,不仅是对象类型。

若是陈述和强制解包

您可使用if语句经过比较可选的against来肯定可选是否包含值nil您使用“等于”运算符(==)或“不等于”运算符(!=执行此比较

若是可选值有一个值,则认为它是“不等于” nil

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

一旦肯定可选的确实包含一个值,就能够经过!在可选名称的末尾添加一个感叹号()来访问其基础值感叹号有效地说:“我知道这个可选确定有价值,请使用它“。这被称为强制展开可选的值:

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

有关详情if,请参阅控制流程

注意

尝试使用!访问不存在的可选值触发运行时错误。nil在使用!强制解开其值以前,请确保可选包含非值。

可选的绑定

您使用可选绑定来查找可选是否包含值,若是是,则使该值可用做临时常量或变量。可选的绑定能够ifwith while语句一块儿用来检查一个可选的值,并把这个值提取到一个常量或变量中,做为单个动做的一部分。ifwhile控制流程中更详细地描述报表

if语句编写一个可选的绑定,以下所示:

  • 若是 constantName = someOptional {
  •     声明
  • }

您能够重写Optionals部分中possibleNumber示例以使用可选绑定而不是强制展开:

  1. if let actualNumber = Int(possibleNumber) {
  2. print("\"\(possibleNumber)\" has an integer value of \(actualNumber)")
  3. } else {
  4. print("\"\(possibleNumber)\" could not be converted to an integer")
  5. }
  6. // Prints ""123" has an integer value of 123"

这段代码能够读做:

“若是Int返回的可选Int(possibleNumber)值包含一个值,则设置一个新的常量调用actualNumber可选值中包含的值。”

若是转换成功,则该actualNumber常量在if语句的第一个分支内可用它已经被包含可选项中的值初始化,因此不须要使用!后缀来访问它的值。在这个例子中,actualNumber只是用来打印转换的结果。

您可使用可选绑定的常量和变量。若是您想操做语句actualNumber第一个分支内的值if,您能够if var actualNumber改成写入,而且可选内容中的值将做为变量而不是常量提供。

您能够根据须要在单个if语句中包含尽量多的可选绑定和布尔条件,并用逗号分隔。若是可选绑定中的nil任何值或任何布尔条件的计算结果false,则整个if语句的条件被认为是false如下if声明是等同的:

  1. if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
  2. print("\(firstNumber) < \(secondNumber) < 100")
  3. }
  4. // Prints "4 < 42 < 100"
  5. if let firstNumber = Int("4") {
  6. if let secondNumber = Int("42") {
  7. if firstNumber < secondNumber && secondNumber < 100 {
  8. print("\(firstNumber) < \(secondNumber) < 100")
  9. }
  10. }
  11. }
  12. // Prints "4 < 42 < 100"

注意

if语句中使用可选绑定建立的常量和变量只能在if语句的主体中使用相反,使用guard语句建立的常量和变量能够在语句以后的代码行中找到guard,如Early Exit中所述

隐含解包选项

如上所述,可选项表示常数或变量被容许具备“无值”。可使用if语句来检查选项,以查看是否存在值,而且可使用可选绑定有条件地解包,以访问可选值(若是存在)。

有时从程序的结构中能够清楚地看到,在第一次设置值以后,可选项将始终有一个值。在这些状况下,每次访问时都不须要检查和打开可选的值,由于能够安全地假定全部的时间都有一个值。

这些选项被定义为隐含的解包选项你写一个隐式解开的可选项,在你想要的可选类型以后放置一个感叹号(String!)而不是一个问号(String?)。

当一个可选的值被确认在第一次定义的可选值以后当即存在时,隐式解包的可选值是有用的,而且能够确定地假定在随后的每一个点都存在。Swift中隐式解包选项的主要用途是在类初始化期间,如Unowned References和Unwinedly Unwrapped Optional Properties中所述

隐式解包可选是幕后的普通可选项,但也能够像非可选值同样使用,而没必要在每次访问时展开可选值。如下示例显示了在以可显式方式访问包装值时,可选字符串与隐式解包的可选字符串之间的行为差​​异String

  1. let possibleString: String? = "An optional string."
  2. let forcedString: String = possibleString! // requires an exclamation mark
  3. let assumedString: String! = "An implicitly unwrapped optional string."
  4. let implicitString: String = assumedString // no need for an exclamation mark

你能够想象一个隐式解包的可选方法,只要使用它就能够自动解包这个可选方法。每次使用时,不要在可选名称后面放置感叹号,而是在声明它时在可选类型后面放置感叹号。

注意

若是隐式解包可选,nil而且您尝试访问其包装的值,则会触发运行时错误。结果与在不包含值的普通可选项以后放置感叹号彻底相同。

你仍然能够像一个普通的可选项那样对待一个隐式的解包可选,来检查它是否包含一个值:

  1. if assumedString != nil {
  2. print(assumedString)
  3. }
  4. // Prints "An implicitly unwrapped optional string."

你也可使用一个带有可选绑定的隐式解包可选方法,在一个语句中检查和解包它的值:

  1. if let definiteString = assumedString {
  2. print(definiteString)
  3. }
  4. // Prints "An implicitly unwrapped optional string."

注意

当变量有可能nil在稍后出现时,不要使用隐式解包的可选项若是您须要nil在变量的生命周期中检查,请始终使用正常的可选类型

错误处理

您可使用错误处理来响应您的程序在执行过程当中可能遇到的错误状况。

与可选择性有关,它可使用值的存在或不存在来传递函数的成功或失败,错误处理容许您肯定失败的根本缘由,而且,若是有必要,将错误传播到程序的另外一部分。

当一个函数遇到一个错误条件时,它会抛出一个错误。而后该函数的调用者能够捕获错误并做出适当的响应。

  1. func canThrowAnError() throws {
  2. // this function may or may not throw an error
  3. }

一个函数指示它能够经过throws在其声明中包含关键字来引起错误当你调用一个可能引起错误的函数时,你try须要在表达式中加上关键字。

Swift自动将错误从当前做用域传出,直到它们被一个catch子句处理

  1. do {
  2. try canThrowAnError()
  3. // no error was thrown
  4. } catch {
  5. // an error was thrown
  6. }

一个do语句建立一个新的包含范围,它容许错误传播到一个或多个catch子句。

如下是错误处理如何用于响应不一样错误条件的示例:

  1. func makeASandwich() throws {
  2. // ...
  3. }
  4. do {
  5. try makeASandwich()
  6. eatASandwich()
  7. } catch SandwichError.outOfCleanDishes {
  8. washDishes()
  9. } catch SandwichError.missingIngredients(let ingredients) {
  10. buyGroceries(ingredients)
  11. }

在这个例子中,makeASandwich()若是没有可用的干净的菜肴,或者若是有任何配料丢失,该功能将会报错。由于makeASandwich()能够抛出一个错误,函数调用被包装在一个try表达式中。经过将函数调用包装在一个do语句中,抛出的任何错误都会传播到提供的catch子句中。

若是没有错误,eatASandwich()则调用函数。若是抛出一个错误,并匹配SandwichError.outOfCleanDishes大小写,那么washDishes()函数将被调用。若是抛出一个错误而且匹配SandwichError.missingIngredients大小写,那么该buyGroceries(_:)函数将被调用,并[String]使用catch模式捕获的相关

错误处理中 详细介绍了抛出,捕获和传播错误

断言和先决条件

断言先决条件是在运行时发生的检查。在执行任何进一步的代码以前,使用它们来确保知足基本条件。若是断言或前提条件中的布尔条件评估为true,则代码执行将像往常同样继续。若是条件评估为false,程序的当前状态是无效的; 代码执行结束,你的应用程序被终止。

您使用断言和先决条件来表达您所作的假设以及编码时的指望,这样您就能够将它们包含在代码中。断言有助于您在开发过程当中发现错误和不正确的假设,而且先决条件可帮助您检测生产中的问题。

除了在运行时验证您的指望外,断言和先决条件也成为代码中有用的文档形式。与上述错误处理中讨论的错误条件不一样,断言和先决条件不用于可恢复或预期的错误。由于失败的断言或先决条件代表一个无效的程序状态,没有办法遇上失败的断言。

使用断言和先决条件不能替代设计代码的方式,以致于不可能出现无效条件。可是,使用它们强制执行有效的数据和状态会致使您的应用程序在发生无效状态时更可预测地终止,并有助于使问题更易于调试。一旦检测到无效状态,当即中止执行也有助于限制由该无效状态形成的损害。

断言和先决条件之间的区别在于它们被检查时:只在调试版本中检查断言,可是在调试版本和生产版本中检查前提条件。在生产构建中,断言内的条件不被评估。这意味着您能够在开发过程当中使用尽量多的断言,而不会影响生产性能。

用断言进行调试

你能够经过调用assert(_:_:file:line:)Swift标准库中函数来编写断言若是条件的结果是,则将此函数传递给计算结果为trueor 的表达式,false并显示要显示的消息false例如:

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

在这个例子中,若是age >= 0计算true结果是代码执行继续,也就是说,若是值age是非负的。若是age上面的代码中的值为负数,则age >= 0评估为false,而且断言失败,则终止该应用程序。

你能够省略断言信息 - 例如,当它只是重复做为散文的条件。

  1. assert(age >= 0)

若是代码已经检查了条件,则使用该assertionFailure(_:file:line:)函数来指示断言失败。例如:

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

执行先决条件

当条件有多是错误的时候使用前提条件,可是对于代码继续执行确定是正确的。例如,使用前提条件来检查下标是否超出范围,或检查函数是否已传递有效值。

你经过调用precondition(_:_:file:line:)函数来编写一个前提条件若是条件的结果是,则将此函数传递给计算结果为trueor 的表达式,false并显示要显示的消息false例如:

  1. // In the implementation of a subscript...
  2. precondition(index > 0, "Index must be greater than zero.")

您也能够调用该preconditionFailure(_:file:line:)函数来指示发生了故障 - 例如,若是采起了开关的默认状况,但全部有效的输入数据都应由交换机的其余状况之一处理。

注意

若是以非检查模式编译(-Ounchecked),则不检查前置条件。编译器假定前置条件老是正确的,并相应地优化了你的代码。可是,fatalError(_:file:line:)不管优化设置如何,该函数都会暂停执行。

您能够fatalError(_:file:line:)在原型开发和早期开发中使用该函数,经过编写fatalError("Unimplemented")存根实现来建立还没有实现的功能的存根。因为致命错误永远不会被优化,与断言或前提条件不一样,您能够确保执行始终中止,若是遇到存根实现。

(原文地址) https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID309

相关文章
相关标签/搜索