iOS开发之Swift学习(三)——基础部分

文章目录:
(1)常量和变量
(2)注释
(3)数值型类型转换
(4)类型别名
(5)布尔值
(6)元组
(7)可选类型
(8)断言

  1. Swift 包含了 C 和 Objective-C 上所有基础数据类型,Int 表示整型值; Double和Float表示浮点型值; Bool是布尔型值; String是文本型数据。 Swift 还提供了三个基本的集合型,Array,Set和Dictionary。
  2. Swift 还增加了 Objective-C 中没有的高阶数据类型比如元组(Tuple)。元组可以让你 创建或者传递一组数据,比如作为函数的返回值时,你可以用一个元组可以返回多个值。
  3. Swift 还增加了可选(Optional)类型,用于处理值缺失的情况。可选表示 “那儿有一个值,并且它等于 x ” 或者 “那儿没有值” 。可选有点像在 Objective-C 中使用 nil ,但是它可以用在任何类型上,不仅仅是 类。可选类型比 Objective-C 中的 nil 指针更加安全也更具表现力,它是 Swift 许多强大特性的重要组成部分。

(1)常量和变量

1. 声明常量和变量

let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0

2. 类型标注

声明常量或者变量的时候可以加上类型标注(type annotation),说明常量或者变量中要存储的值的类 型。如果要添加类型标注,需要在常量或者变量名后面加上一个冒号和空格,然后加上类型名称。

var welcomeMessage: String

可以在一行中定义多个同样类型的变量,用逗号分割,并在最后一个变量名之后添加类型标注:

var red, green, blue: Double

注意: 一般来说很少需要写类型标注。如果你在声明常量或者变量的时候赋了一个初始值,Swift可以推断出这个常量或者变量的类型。在上面的例子中,没有给 welcomeMessage 赋初始值,所以变量welcomeMessage的类型是通过一个类型标注指定的,而不是通过初始值推断的。

3. 常量和变量的命名

可以用任何字符作为常量和变量名,包括 Unicode 字符:

let π = 3.14159
let 你好 = "你好世界" let ?? = "dogcow"

4. 输出常量和变量

用 print(_:separator:terminator:) 函数来输出当前常量或变量的值:

(2)注释

多行注释可以嵌套

(3)数值型类型转换

整数和浮点数转换:

整数和浮点数的转换必须显式指定类型:

let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine // pi 等于 3.14159,所以被推测为 Double 类型

常量 three 的值被用来创建一个 Double 类型的值,所以加号两边的数类型须相同。如果不进行 转换,两者无法相加。

浮点数到整数的反向转换:(用 Double 或者 Float 类型来初始化:)
let integerPi = Int(pi)
// integerPi 等于 3,所以被推测为 Int 类型
当用这种方式来初始化一个新的整数值时,浮点值会被截断。也就是说 4.75 会变成 4 , -3.9 会变成 -3 。

(4)类型别名

类型别名(type aliases)就是给现有类型定义另一个名字。可以使用 typealias 关键字来定义类型别名。当想要给现有类型起一个更有意义的名字时,类型别名非常有用。

typealias AudioSample = UInt16
var maxAmplitudeFound = AudioSample.min // maxAmplitudeFound 现在是 0

(5)布尔值

Swift 有一个基本的布尔(Boolean)类型,叫做 Bool 。布尔值指逻辑上的值,因为它们只能是真或者假。Swift 有两个布尔常量,true 和 false:

let orangesAreOrange = true
let turnipsAreDelicious = false

写条件语句比如 语句的时候,布尔值非常有用:

if turnipsAreDelicious {
     print("Mmm, tasty turnips!")
 } else {
     print("Eww, turnips are horrible.")
}
// 输出 "Eww, turnips are horrible."

(6)元组

  1. 元组(tuples)把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型。
let http404Error = (404, "Not Found")
// http404Error 的类型是 (Int, String),值是 (404, "Not Found")
  1. 将一个元组的内容分解(decompose)成单独的常量和变量,然后就可以正常使用它们了:
let (statusCode, statusMessage) = http404Error 
print("The status code is \(statusCode)")
// 输出 "The status code is 404"
print("The status message is \(statusMessage)") 
// 输出 "The status message is Not Found"
  1. 如果只需要一部分元组值,分解的时候可以把要忽略的部分用下划线( _ )标记:
let (justTheStatusCode, _) = http404Error 
print("The status code is \(justTheStatusCode)") 
// 输出 "The status code is 404"
  1. 可以通过下标来访问元组中的单个元素,下标从零开始:
print("The status code is \(http404Error.0)")
// 输出 "The status code is 404"
print("The status message is \(http404Error.1)") 
// 输出 "The status message is Not Found"
  1. 可以在定义元组的时候给单个元素命名:
let http200Status = (statusCode: 200, description: "OK")

给元组中的元素命名后,可以通过名字来获取这些元素的值:

print("The status code is \(http200Status.statusCode)")
// 输出 "The status code is 200"
print("The status message is \(http200Status.description)") 
// 输出 "The status message is OK"

作为函数返回值时,元组非常有用。一个用来获取网页的函数可能会返回一个 (Int, String) 元组来描述是否获取成功。和只能返回一个类型的值比较起来,一个包含两个不同类型值的元组可以让函数的返回信息更有用。

(7)可选类型

1.使用可选类型(optionals)来处理值可能缺失的情况。可选类型表示:
• 有值,等于 x
或者
• 没有值

Swift 的 Int 类型有一种构造器,作用是将一个 String 值转换成一个 Int 值。然而,并 不是所有的字符串都可以转换成一个整数。字符串 "123" 可以被转换成数字 123 ,但是字符串 "hello, wor ld" 不行。

使用这种构造器来尝试将一个 String 转换成 Int :

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber 被推测为类型 "Int?", 或者类型 "optional Int"

因为该构造器可能会失败,所以它返回一个可选类型(optional) Int ,而不是一个 Int 。一个可选的 Int 被写作 Int? 而不是 Int 。问号暗示包含的值是可选类型,也就是说可能包含 Int 值也可能不包含值。(不 能包含其他任何值比如 Bool 值或者 String 值。只能是 Int 或者什么都没有。)

2.nil
可以给可选变量赋值为 nil 来表示它没有值:

var serverResponseCode: Int? = 404
// serverResponseCode 包含一个可选的 Int 值 404 
serverResponseCode = nil
// serverResponseCode 现在不包含值

注意:
nil 不能用于非可选的常量和变量。如果你的代码中有常量或者变量需要处理值缺失的情况,请把它们声明成对应的可选类型。

如果声明一个可选常量或者变量但是没有赋值,它们会自动被设置为 nil :

var surveyAnswer: String?
// surveyAnswer 被自动设置为 nil

注意:
Swift 的 nil 和 Objective-C 中的 nil 并不一样。在 Objective-C 中, nil 是一个指向不存在对象的指针。在 Swift 中, nil 不是指针——它是一个确定的值,用来表示值缺失。任何类型的可选状态都可以被设置为 nil ,不只是对象类型。

3.if 语句以及强制解析
可以使用 if 语句和 nil 比较来判断一个可选值是否包含值。使用“相等”(==)或“不等”( != )来执行比较。
如果可选类型有值,它将不等于 nil :

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

当确定可选类型确实包含值之后,可以在可选的名字后面加一个感叹号( ! )来获取值。这个惊叹号表示“我知道这个可选有值,请使用它。”这被称为可选值的强制解析(forced unwrapping):(也就是通常说的解包)

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

注意:
使用 ! 来获取一个不存在的可选值会导致运行时错误。使用 ! 来强制解析值之前,一定要确定可选包含一 个非 nil 的值。

4.可选绑定
使用可选绑定(optional binding)来判断可选类型是否包含值,如果包含就把值赋给一个临时常量或者变 量。可选绑定可以用在 if 和 while 语句中,这条语句不仅可以用来判断可选类型中是否有值,同时可以将可选类型中的值赋给一个常量或者变量。

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

这段代码可以被理解为:(讲的太清楚明了了)
“如果 Int(possibleNumber) 返回的可选 Int 包含一个值,创建一个叫做 actualNumber 的新常量并将可选 包含的值赋给它。”
如果转换成功, actualNumber 常量可以在 if 语句的第一个分支中使用。它已经被可选类型 包含的 值初始化 过,所以不需要再使用 ! 后缀来获取它的值。在这个例子中,actualNumber 只被用来输出转换结果。
你可以在可选绑定中使用常量和变量。如果你想在if语句的第一个分支中操作 actualNumber 的值,你可以改 成 if var actualNumber ,这样可选类型包含的值就会被赋给一个变量而非常量。
你可以包含多个可选绑定或多个布尔条件在一个 if 语句中,只要使用逗号分开就行。只要有任意一个可选绑定 的值为nil,或者任意一个布尔条件为false,则整个if条件判断为false,这时你就需要使用嵌套 if 条 件语句来处理,如下所示:

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

注意: 在 if 条件语句中使用常量和变量来创建一个可选绑定,仅在 if 语句的句中( body )中才能获取到 值。相反,在 guard 语句中使用常量和变量来创建一个可选绑定,仅在 guard 语句外且在语句后才能获取 到值

5.隐式解析可选类型
(1)可选类型暗示了常量或者变量可以“没有值”。可选可以通过 if 语句来判断是否有值,如果有值的话可以通过可选绑定来解析值。
(2)有时候在程序架构中,第一次被赋值之后,可以确定一个可选类型总会有值。在这种情况下,每次都要判断和解析可选值是非常低效的,因为可以确定它总会有值。
这种类型的可选状态被定义为隐式解析可选类型(implicitly unwrapped optionals)。把想要用作可选的类型的后面的问号( String? )改成感叹号( String! )来声明一个隐式解析可选类型。
(3)当可选类型被第一次赋值之后就可以确定之后一直有值的时候,隐式解析可选类型非常有用。隐式解析可选类型 主要被用在 Swift 中类的构造过程中
(4)一个隐式解析可选类型其实就是一个普通的可选类型,但是可以被当做非可选类型来使用,并不需要每次都使用 解析来获取可选值。下面的例子展示了可选类型 String 和隐式解析可选类型 String 之间的区别:

let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // 需要感叹号来获取值
let assumedString: String! = "An implicitly unwrapped optional string." let implicitString: String = assumedString // 不需要感叹号
可以把隐式解析可选类型当做一个可以自动解析的可选类型。要做的只是声明的时候把感叹号放到类型的结尾,而不是每次取值的可选名字的结尾。

注意:
 如果你在隐式解析可选类型没有值的时候尝试取值,会触发运行时错误。和你在没有值的普通可选类型后面加一个惊叹号一样。

(5)仍然可以把隐式解析可选类型当做普通可选类型来判断它是否包含值:

if assumedString != nil {
     print(assumedString)
}
// 输出 "An implicitly unwrapped optional string."

也可以在可选绑定中使用隐式解析可选类型来检查并解析它的值:

if let definiteString = assumedString {
     print(definiteString)
}
// 输出 "An implicitly unwrapped optional string."

注意:
如果一个变量之后可能变成 nil 的话请不要使用隐式解析可选类型。如果你需要在变量的生命周期中判断是否 是 nil 的话,请使用普通可选类型。

(8)断言

可选类型可以让你判断值是否存在,你可以在代码中优 地处理值缺失的情况。然而,在某些情况下,如果值缺 失或者值并不满足特定的条件,你的代码可能没办法继续执行。这时,你可以在你的代码中触发一个 断言(assertion) 来结束代码运行并通过调试来找到值缺失的原因。

  1. 使用断言进行调试
    断言会在运行时判断一个逻辑条件是否为 true 。从字面意思来说,断言“断言”一个条件是否为真。可以使用断言来保证在运行其他代码之前,某些重要的条件已经被满足。如果条件判断为 true ,代码运行会继续进行;如果条件判断为 false ,代码执行结束,应用被终止。
    如果代码在调试环境下触发了一个断言,比如你在 Xcode 中构建并运行一个应用,可以清楚地看到不合法的状态发生在哪里并检查断言被触发时应用的状态。此外,断言允许附加一条调试信息。
    可以使用全局 assert(::file:line:) 函数来写一个断言。向这个函数传入一个结果为 true 或者 false 的表达式以及一条信息,当表达式的结果为 false 的时候这条信息会被显示:
let age = -3
assert(age >= 0, "A person's age cannot be less than zero") 
// 因为 age < 0,所以断言会触发

在这个例子中,只有 age >= 0 为 true 的时候,即 age 的值非负的时候,代码才会继续执行。如果 age 的值是负数,就像代码中那样, age >= 0 为 false ,断言被触发,终止应用。
如果不需要断言信息,可以省略,就像这样:

assert(age >= 0)
注意:
当代码使用优化编译的时候,断言将会被禁用,例如在 Xcode 中,使用默认的 target Release 配置选项来 build 时,断言会被禁用。
  1. 何时使用断言
    当条件可能为假时使用断言,但是最终一定要保证条件为真,这样代码才能继续运行。断言的适用情景:
    • 整数类型的下标索引被传入一个自定义下标实现,但是下标索引值可能太小或者太大。
    • 需要给函数传入一个值,但是非法的值可能导致函数不能正常执行。
    • 一个可选值现在是 nil ,但是后面的代码运行需要一个非 nil 值。
    注意:
    断言可能导致你的应用终止运行,所以你应当仔细设计你的代码来让非法条件不会出现。然而,在应用发布之前,有时候非法条件可能出现,这时使用断言可以快速发现问题。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容