第1天 变量、常量、字符串和数字
SwiftUI 是一个强大的框架,用于为 iOS、macOS、tvOS 甚至 watchOS 构建用户交互应用。但没有编程语言就无法开发软件,所以 SwiftUI 的背后是 Swift 本身:这是一种强大、灵活且现代化的编程语言,你将在所有 SwiftUI 应用中使用它。
正如马克・吐温曾经说过的:“取得进步的秘诀在于开始行动。” 好吧,你现在就要开始了,所以我们将深入学习 Swift 中的变量、常量和简单数据类型。
今天你需要完成七个教程。 如果你想更深入地了解每个主题,有一些可选的扩展阅读,但除非你愿意且有时间,否则不需要阅读。无论如何,有一些简短的测试可以帮助确保你理解了关键概念。
我知道,我知道:你很想继续观看更多视频并参加除下面链接之外的更多测试,但请记住:不要急于求成!每天学习一小时,坚持下去,比断断续续地学一大块要好得多。
1.1 为什么选择 Swift?
作者:Paul Hudson 2021 年 10 月 1 日 已针对 Xcode 16.4 更新
世界上有很多编程语言,但我相信你会非常喜欢学习 Swift。部分原因是出于实际考虑 —— 你可以在 App Store 上赚很多钱!—— 但也有很多技术层面的原因。
你要知道,Swift 是一种相对较新的语言,2014 年才推出。这意味着它没有许多古老语言所存在的冗余代码问题,而且通常情况下,解决某个特定问题只有一种方法。
同时,作为一种如此新的编程语言,Swift 借鉴了各种基于旧语言成功经验(有时也包含错误)的新理念。例如,它降低了意外编写不安全代码的可能性,让编写清晰易懂的代码变得非常容易,并且它支持世界上所有语言,所以你永远不会遇到其他语言中常见的那些奇怪的字符错误。
Swift 本身只是一门语言,并非为在屏幕上绘制内容而设计。当涉及到用 Swift 开发软件时,你会用到 SwiftUI:苹果的强大框架,它可以创建文本、按钮、图像、用户交互等等。顾名思义,SwiftUI 是为 Swift 量身打造的 —— 它确实充分利用了该语言所提供的强大功能和安全性,这使得构建真正强大的应用程序变得异常快捷。
所以,你应该学习 Swift,因为你可以用它赚很多钱,还因为它在很多方面都表现出色。没有冗余,没有困惑,只有强大的功能任你掌控。还有什么不喜欢的呢?
1.2 关于本课程
作者:Paul Hudson 2021 年 10 月 1 日 已更新至 Xcode 16.4 版本
自 2014 年 Swift 语言推出以来,我就一直在教人们编写 Swift 代码。到目前为止,Hacking with Swift 已经成为全球最大的专注于教授 Swift 的网站。
在这个过程中,我学到了很多东西:哪些主题最为重要,如何将这些主题组织成流畅且连贯的学习流程,而最重要的是,如何帮助学习者记住他们所学的内容。本课程就是所有这些经验的成果。
与我之前的作品不同,本课程并不试图教你 Swift 的方方面面,而是将更多时间花在那些最为重要的功能子集上 —— 就是那些你在构建每个应用时都会反复用到的功能。当然,课程中也涵盖了一些高级语言特性,但这些都是我根据其实用性精心挑选的。当你学完这本书后,可能会想继续学习一些更高级的特性,但我猜你更愿意忙着学习如何使用 SwiftUI。
本书的每一章都有文字和视频两种形式,但它们涵盖的内容完全相同,所以你可以选择最适合自己的学习方式。如果你观看视频,会发现我有时会用幻灯片介绍主题,有时会在 Xcode 中进行演示。这可能会让人觉得有些重复,但这是有意为之 —— 有很多内容需要学习,而如果每个内容你只看一次,是很难记住的!
最后还有一点:你可能会注意到很多章节都以 “如何……” 开头,这也是有意安排的 —— 这本书旨在以实践的方式向你展示如何做事,而不是深入探讨理论。理论固然重要,在你继续学习的过程中会遇到很多理论知识,但在这里,重点始终是实用性,因为我相信学习新事物的最佳方式是亲自尝试。
编程是一门艺术:不该在本该画画的时候,把所有时间都花在削铅笔上。
1.3 如何跟上学习进度
作者:Paul Hudson 2023 年 9 月 22 日 已针对 Xcode 16.4 更新
这本书中展示了大量代码,我非常鼓励你亲自尝试所有代码 —— 把代码输入到你的电脑中,运行它并查看输出结果,然后进行一些实验以确保你理解了代码。
要运行本书中的代码,你需要从 Mac App Store 安装 Xcode 15.0 或更高版本。它是免费的,包含你跟上学习进度所需的一切。
我们将使用 Swift Playground 来运行本书中的所有代码。你可以通过启动 Xcode,然后进入 “文件” 菜单并选择 “新建”>“Playground” 来创建一个。当被问及要创建哪种类型的 Playground 时,从 macOS 选项卡中选择 “空白”,然后将其保存到你容易找到的地方。
Playground 就像小小的沙盒,你可以在其中轻松尝试 Swift 代码,在代码旁边就能看到工作成果。你可以使用一个 Playground 来完成所有工作,也可以为每一章创建一个新的 Playground—— 做任何对你来说最有效的事情。
提示: 第一次在 Playground 中运行代码可能需要几秒钟才能启动,但后续运行会很快。
1.4 如何创建变量和常量
作者:Paul Hudson 2021 年 10 月 1 日 已针对 Xcode 16.4 更新
在编写程序时,你总会需要存储一些数据。可能是用户刚刚输入的姓名,可能是从互联网上下载的一些新闻报道,也可能是你刚刚完成的复杂计算的结果。
Swift 提供了两种存储数据的方式,具体取决于您是否希望数据随时间变化。创建新的 Playground 时会自动使用第一种方式,因为它包含以下代码:
var greeting = "Hello, playground"这行代码创建了一个名为 greeting 的变量,由于它是变量,其值可以变化—— 在程序运行过程中可以被修改。
提示: macOS playground 中的另一行代码是 import Cocoa,它引入了苹果提供的大量代码集合,以便更轻松地构建应用程序。这其中包含了许多重要功能,所以请不要删除它。
这行代码中实际上包含四个语法部分:
var关键字表示 “创建一个新变量”,这样可以节省一些输入。- 我们将变量命名为
greeting。你可以给变量起任何名字,但大多数时候你会希望名字具有描述性。 - 等号用于给变量赋值。你也可以不在等号两边加空格,但这是最常见的写法。
- 我们赋予的值是文本 “Hello, playground”。注意,文本是写在双引号内的,这样 Swift 就能知道文本的开始和结束位置。
如果你使用过其他语言,可能会注意到我们的代码行末尾不需要分号。Swift允许使用分号,但这种情况非常少见 —— 只有当你出于某种原因想在同一行写两段代码时才需要用到。
创建变量后,你可以随时修改它的值:
var name = "Ted"
name = "Rebecca"
name = "Keeley"这段代码创建了一个名为 name 的新变量,并给它赋值为 “Ted”。然后它被修改了两次,首先改为 “Rebecca”,接着改为 “Keeley”—— 这里没有再次使用 var,因为我们是在修改已有的变量,而不是创建新变量。你可以根据需要多次修改变量,每次修改时旧值都会被丢弃。(你当然可以在变量中放入不同的文本,但我是电视剧《足球教练》的忠实粉丝,所以就用了 Ted 这个名字。而且可以预见,在接下来的章节中还会有其他《足球教练》的引用等等。)
如果你不希望某个值被改变,就需要使用常量。创建常量的方式几乎和创建变量一样,只是我们用 let 而不是 var,如下所示:
let character = "Daphne"使用 let 创建的是常量,其值不能被改变。Swift 绝对不允许修改常量的值,如果尝试修改,会显示一个明显的错误。
不相信吗?试着在 Xcode 中输入这段代码:
let character = "Daphne"
character = "Eloise"
character = "Francesca"同样,第二行和第三行中没有 let 关键字,因为我们不是在创建新的常量,只是试图修改已有的那个。但是,就像我说的,这行不通 —— 你不能修改常量,否则它就不叫常量了!
如果你好奇的话,“let” 来源于数学领域,在数学中人们会说 “令 x 等于 5” 之类的话。
重要提示: 请删除显示错误的那两行代码 —— 你确实不能修改常量!
学习 Swift 时,你可以让 Xcode 打印出任何变量的值。在实际应用中你不会经常用到这个功能,因为用户看不到打印的内容,但作为一种查看数据内部情况的简单方法,它非常有用。
例如,我们可以在每次设置变量值时打印出来 —— 试着在你的 playground 中输入这段代码:
var playerName = "Roy"
print(playerName)
playerName = "Dani"
print(playerName)
playerName = "Sam"
print(playerName)提示: 你可以通过点击代码左侧的蓝色播放图标来运行 Xcode playground 中的代码。如果你沿着蓝色条上下移动,会发现播放图标也会跟着移动 —— 这让你可以运行到某个特定点的代码,但在这里大多数时候你会想运行到最后一行。
你可能已经注意到,我把变量命名为 playerName,而不是 playername、player_name 或其他形式。这是一种选择:Swift 并不真正关心你的常量和变量叫什么名字,只要你在所有地方都用相同的方式引用它们就行。所以,我不能先使用 playerName,然后再用 playername——Swift 会认为这两个是不同的名字。
虽然 Swift 不关心我们如何给数据命名,但我使用的命名风格是 Swift 开发者中的标准 —— 我们称之为约定。如果你好奇的话,这种风格叫做 “驼峰式命名法”,因为名称中第二个及以后的单词以大写字母开头,就像小驼峰一样:
let managerName = "Michael Scott"
let dogBreed = "Samoyed"
let meaningOfLife = "How many roads must a man walk down?"如果可以的话,尽量使用常量而不是变量 —— 这不仅能让 Swift 有机会对代码进行一些优化,还能让 Swift 确保你不会意外地修改常量的值。
【可选阅读】为什么 Swift 有变量?
作者:Paul Hudson 2021 年 10 月 25 日 已针对 Xcode 16.4 更新
变量允许我们在程序中存储临时信息,并且是几乎每个 Swift 程序的关键组成部分。归根结底,你的程序总会以某种方式处理数据:或许是让用户输入待办事项然后勾选完成,或许是让他们在荒岛上闲逛为贪婪的浣熊干活,又或者是读取设备时间并在时钟上显示。不管怎样,你都是在获取某种数据,对其进行某种处理,然后展示给用户。
当然,“以某种方式处理数据” 才是真正的魔力所在,因为这正是你绝妙的应用创意得以实现的部分。但在内存中存储数据 —— 比如保存用户输入的内容,或者从互联网上下载的东西 —— 就需要用到变量了。
一旦使用 var 创建了一个变量,你就可以随时更改它的值,而无需再次使用 var。例如:
var favoriteShow = "女子监狱"
favoriteShow = "善地"
favoriteShow = "神秘博士"如果有帮助的话,你可以把 var 理解为 “创建一个新变量”。所以,上面第一行代码大声读出来可能是 “创建一个名为 favoriteShow 的新变量,并给它赋值为《女子监狱》”。第二行和第三行没有 var,所以它们是修改已有变量的值,而不是创建新变量。
现在试想一下,如果三行都加上 var—— 每次都写 var favoriteShow。这就没什么意义了,因为你相当于在说 “创建一个名为 favoriteShow 的新变量” 三次,而第一次创建之后,这个变量显然就不再是新的了。Swift 会将此标记为错误,这意味着在你给变量取不同的名字之前,代码无法运行。
这听起来可能有点烦人,但相信我:这是有帮助的!Swift 希望你表达清晰:你是想修改一个已有的变量(如果是这样,第二次及以后就去掉 var),还是想创建一个新变量(如果是这样,就给它取个别的名字)。
最后一点:尽管变量是许多 Swift 程序的核心,但你会发现有时候最好避免使用它们。后面会详细讲这一点!
【可选阅读】为什么 Swift 既有变量又有常量?
作者:Paul Hudson 2020 年 5 月 21 日 已针对 Xcode 16.4 更新
变量是在程序中存储临时数据的好方法,但 Swift 给了我们另一个更好的选择:常量。常量在各方面都和变量一样,只有一个重要区别:一旦被赋值,就不能再改变其值。
Swift 非常喜欢常量,事实上,如果你创建了一个变量但从未修改过它的值,Swift 会建议你使用常量。原因在于避免问题:你创建的任何变量都可以随时被你多次修改,所以你会失去一些控制 —— 你存储的重要用户数据可能在未来的任何时候被删除或替换。
常量不允许我们在赋值后修改其值,所以这有点像和 Swift 签订了一份协议:你在说 “这个值很重要,无论我做什么都不要让我修改它”。当然,你也可以尝试和变量签订同样的协议,但键盘上的一个失误就可能搞砸一切,而 Swift 对此无能为力。只要把 var 改成 let 使用常量,你就是在让 Swift 确保这个值永远不会改变,这也就成了一件你无需再担心的事。
【练习题】变量和常量
问题 1:以下哪些代码行创建了新变量?
选项 A:
message = "早上好,戴夫!"选项 B:
var operatingSystem = "macOS"问题 2:以下哪些代码行创建了常量?
选项 A:
let username = "twostraws"选项 B:
var status = "success"1.5 如何创建字符串
作者:Paul Hudson 2021 年 11 月 25 日 已针对 Xcode 16.4 更新
当你将文本赋值给常量或变量时,我们称之为 “字符串(string)”—— 可以想象成一串拼字游戏的字母牌串在一起组成一个单词。
Swift 的字符串以双引号开始和结束,而引号内部的内容则由你决定。你可以使用简短的字母文本,像这样:
let actor = "Denzel Washington"你也可以使用标点符号、表情符号和其他字符,例如:
let filename = "paris.jpg"
let result = "⭐️ You win! ⭐️"你甚至可以在字符串中使用其他双引号,只要注意在它们前面加一个反斜杠,这样 Swift 就会明白这些双引号是字符串内部的内容,而不是用来结束字符串的:
let quote = "Then he tapped a sign saying \"Believe\" and walked away."别担心 —— 如果你漏掉了反斜杠,Swift 肯定会大声提示你的代码有问题。
字符串的长度没有实际限制,这意味着你可以用一个字符串来存储非常长的内容,比如莎士比亚的全部作品。不过,你会发现 Swift 不喜欢字符串中有换行符。所以,下面这种代码是不允许的:
let movie = "A day in
the life of an
Apple engineer"但这并不意味着你不能创建跨多行的字符串,只是 Swift 需要你对它们进行特殊处理:不是在字符串两边各用一组引号,而是用三组引号,像这样:
let movie = """
A day in
the life of an
Apple engineer
"""这种多行字符串并不常用,但至少你知道该怎么做了:开头和结尾的三重引号各占一行,中间是你的字符串内容。
创建字符串后,你会发现 Swift 提供了一些有用的功能来处理其内容。随着学习的深入,你会了解更多这样的功能,但这里我想先介绍三个。
首先,你可以在变量或常量名后面加上.count来获取字符串的长度:
print(actor.count)因为actor的内容是 “Denzel Washington”,所以这会输出 17—— 包括名字中的每个字母,以及中间的空格。
如果你不想直接打印字符串的长度,也可以把它赋值给另一个常量,像这样:
let nameLength = actor.count
print(nameLength)第二个有用的功能是uppercased(),它会返回一个相同的字符串,但其中所有字母都变成大写:
print(result.uppercased())是的,这里需要加上圆括号,而count不需要。原因随着你的学习会变得更清楚,但在 Swift 学习的初期,我们可以这样简单理解:如果你是让 Swift 读取一些数据,就不需要圆括号;但如果是让 Swift 执行一些操作,就需要圆括号。随着学习的深入,你会发现这并不完全准确,但目前这样理解足以让你继续学习下去。
最后一个有用的字符串功能叫做hasPrefix(),它可以告诉我们一个字符串是否以我们指定的某些字母开头:
print(movie.hasPrefix("A day"))还有一个对应的hasSuffix()功能,它用来检查字符串是否以某些文本结尾:
print(filename.hasSuffix(".jpg"))重要提示: Swift 中的字符串是区分大小写的,这意味着使用filename.hasSuffix(".JPG")会返回 false,因为字符串中的字母是小写的。
字符串在 Swift 中功能非常强大,我们这里只是触及了它们所能做的事情的表面!
【可选阅读】为什么 Swift 需要多行字符串?
作者:Paul Hudson 2020 年 5 月 28 日 已针对 Xcode 16.4 更新
Swift 的标准字符串以引号开始和结束,但绝不能包含任何换行符。例如,这是一个标准字符串:
var quote = "Change the world by being yourself"对于短小的文本片段来说,这没什么问题,但如果你想存储大量文本,在源代码中就会显得很不美观。这就是多行字符串的用武之地:如果你使用三重引号,就可以根据需要将字符串写成任意多行,这意味着文本在代码中仍然易于阅读:
var burns = """
The best laid schemes
O’ mice and men
Gang aft agley
"""Swift 会将字符串中的这些换行符视为文本本身的一部分,所以这个字符串实际上包含三行内容。
提示: 有时你可能希望在代码中使用长字符串而不换行,但这种情况相当少见。具体来说,如果你打算与他人共享代码,这一点往往很重要 —— 如果他们在你的程序中看到一条错误信息,可能会想在你的代码中搜索它,而如果你的代码将其拆分成了多行,他们的搜索可能会失败。
【练习题】多行字符串
问题 1/12:这段代码正确地创建了多行字符串 —— 对还是错?
var burns = """
The best laid schemes
o' mice an' men
gang aft agley
"""问题 2/12:这段代码正确地创建了多行字符串 —— 对还是错?
var shakespeare = """
To be or not to be
that is the question
"""问题 3/12:这段代码正确地创建了多行字符串 —— 对还是错?
var joseph = """
When I am an old woman,
I shall wear purple
with a red hat that doesn't go,
and doesn't suit me
"""问题 4/12:这段代码正确地创建了多行字符串 —— 对还是错?
var eliot = "This is the way the world ends
Not with a bang but with a whimper"问题 5/12:这段代码正确地创建了多行字符串 —— 对还是错?
var tennyson = """
Tis better to have loved
and lost than never
to have loved at all
"""问题 6/12:这段代码正确地创建了多行字符串 —— 对还是错?
var lear = "The Owl and the Pussy-cat went to sea
In a beautiful pea-green boat,
They took some honey, and plenty of money,
Wrapped up in a five-pound note."问题 7/12:这段代码正确地创建了多行字符串 —— 对还是错?
var wordsworth = """
I wandered lonely as a cloud
that floats on high
o'er vales and hills
"""问题 8/12:这段代码正确地创建了多行字符串 —— 对还是错?
var coleridge = """
Water, water, everywhere
and not a drop to drink"""问题 9/12:这段代码正确地创建了多行字符串 —— 对还是错?
var henley = """I am the master of my fate
I am the captain of my soul"""问题 10/12:这段代码正确地创建了多行字符串 —— 对还是错?
var rossetti = """
For if the darkness and corruption leave
A vestige of the thoughts that once I had,
Better by far you should forget and smile
Than that you should remember and be sad.
"""问题 11/12:这段代码正确地创建了多行字符串 —— 对还是错?
var shelley = "My name is Ozymandias, King of Kings
Look on my works, ye mighty, and despair!"问题 12/12:这段代码正确地创建了多行字符串 —— 对还是错?
var brooke = ""If I should die,
think only this of me
There is some corner of a foreign field
That is forever England."1.6 如何存储整数
作者:Paul Hudson 2022 年 5 月 12 日 已针对 Xcode 16.4 更新
当你处理像 3、5、50 或 500 万这样的整数时,你所处理的是 Swift 中称为整数的类型,简称为Int—— 如果你好奇的话,“integer” 源自拉丁语,意思是 “完整的”。
创建一个新的整数和创建一个字符串很像:根据你想要常量还是变量来使用let或var,提供一个名称,然后给它赋值。例如,我们可以像这样创建一个score常量:
let score = 10整数可以非常大 —— 超过十亿、万亿、千万亿,甚至达到百万亿,也可以非常小 —— 它们可以存储小到百万亿的负数。
当你手工写出数字时,可能很难看清具体数值。例如,这个数字是多少?
let reallyBig = 100000000如果我们手工写这个数字,可能会写成 “100,000,000”,这时就很清楚这是 1 亿。Swift 也有类似的功能:你可以使用下划线_来随意分隔数字。
所以,我们可以把上面的代码改成这样:
let reallyBig = 100_000_000Swift 其实并不在意下划线的使用方式,所以如果你想,也可以这样写:
let reallyBig = 1_00__00___00____00最终结果是一样的:reallyBig被设置为一个值为 100,000,000 的整数。
当然,你也可以通过学校里学过的算术运算符,用其他整数来创建新的整数:+用于加法,-用于减法,*用于乘法,/用于除法。
例如:
let lowerScore = score - 2
let higherScore = score + 10
let doubledScore = score * 2
let squaredScore = score * score
let halvedScore = score / 2
print(score)除了每次都创建新的常量,Swift 还有一些特殊的操作,可以以某种方式调整一个整数,并将结果赋回给原来的数字。
例如,这里创建了一个值为 10 的counter变量,然后给它加 5:
var counter = 10
counter = counter + 5不用写成counter = counter + 5,你可以使用简写运算符+=,它可以直接把一个数加到对应的整数上:
counter += 5
print(counter)这两种写法效果完全一样,只是后者更简洁。我们把这些称为复合赋值运算符,它们还有其他形式:
counter *= 2
print(counter)
counter -= 10
print(counter)
counter /= 2
print(counter)在结束关于整数的内容之前,我想最后提一点:和字符串一样,整数也有一些有用的附加功能。例如,你可以调用整数的isMultiple(of:)方法来判断它是否是另一个整数的倍数。
所以,我们可以这样判断 120 是否是 3 的倍数:
let number = 120
print(number.isMultiple(of: 3))我在这里是对一个常量调用isMultiple(of:)方法,但你也可以直接使用数字:
print(120.isMultiple(of: 3))【练习题】字符串和整数
问题 1/6:哪段代码创建了一个整数?
选项 1:
var mortgageRemaining = 100_000选项 2:
var dogBreed = "samoyed"问题 2/6:哪段代码创建了一个整数?
选项 1:
var speed = 88选项 2:
var age = "23"问题 3/6:哪段代码创建了一个整数?
选项 1:
var repeatCount = 82选项 2:
var selectedWood = "mahogany"问题 4/6:哪段代码创建了一个整数?
选项 1:
var highScore = 328_556选项 2:
var sizeInInches = "27"问题 5/6:哪段代码创建了一个整数?
选项 1:
var currentSong = "Rainbow to the Stars"选项 2:
var power = 9001问题 6/6:哪段代码创建了一个整数?
选项 1:
var winner = "Miguel"选项 2:
var rating = 51.7 如何存储小数
作者:Paul Hudson 2021 年 10 月 1 日 已针对 Xcode 16.4 更新
当你处理诸如 3.1、5.56 或 3.141592654 之类的小数时,你所处理的是 Swift 中所谓的浮点数。这个名称源于计算机存储这些数字的复杂方式:计算机试图在相同的存储空间内存储像 123,456,789 这样非常大的数和像 0.0000000001 这样非常小的数,而实现这一点的唯一方法是根据数字的大小移动小数点的位置。
这种存储方式使得小数对程序员来说是出了名的棘手,通过两行 Swift 代码你就能略知一二:
let number = 0.1 + 0.2
print(number)运行这段代码时,它不会打印出 0.3。相反,它会打印出 0.30000000000000004—— 也就是 0.3 后面跟着 15 个 0,再加上一个 4,原因嘛…… 就像我说的,这很复杂。
稍后我会详细解释为什么会这么复杂,但首先让我们关注重要的内容。
首先,当你创建一个浮点数时,Swift 会将其视为Double类型。Double是 “双精度浮点数” 的缩写,我知道这个名字很奇怪 —— 多年来,我们处理浮点数的方式发生了很大变化,尽管 Swift 在简化这一点上做得很好,但你有时可能会遇到一些更复杂的旧代码。在这种情况下,这意味着 Swift 分配的存储空间是一些较旧语言的两倍,这使得Double可以存储非常大的数。
其次,Swift 认为小数与整数是完全不同的数据类型,这意味着你不能将它们混合使用。毕竟,整数总是 100% 精确的,而小数则不是,所以除非你明确要求,否则 Swift 不会允许你将两者混合使用。
实际上,这意味着你不能做诸如将整数与小数相加之类的操作,因此下面这种代码会产生错误:
let a = 1
let b = 2.0
let c = a + b是的,我们能看出b实际上只是伪装成小数的整数 2,但 Swift 仍然不允许这段代码运行。这被称为类型安全:Swift 不会让我们意外地混合不同类型的数据。
如果你想让它们可以相加,你需要明确告诉 Swift,要么将b中的Double类型视为Int类型:
let c = a + Int(b)要么将a中的Int类型视为Double类型:
let c = Double(a) + b第三,Swift 会根据你提供的数字来决定你想要创建的是Double类型还是Int类型 —— 如果数字中有小数点,那它就是Double类型,否则就是Int类型。是的,即便是小数点后面的数字都是 0 也不例外。
例如:
let double1 = 3.1
let double2 = 3131.3131
let double3 = 3.0
let int1 = 3结合类型安全,这意味着一旦 Swift 确定了某个常量或变量的数据类型,它就必须始终存储该类型的数据。这意味着下面这段代码是可行的:
var name = "Nicolas Cage"
name = "John Travolta"但下面这种代码则不行:
var name = "Nicolas Cage"
name = 57这段代码告诉 Swiftname将存储一个字符串,但随后却试图在其中放入一个整数。
最后,小数拥有与整数相同的运算符和复合赋值运算符:
var rating = 5.0
rating *= 2许多较旧的 API 使用一种略有不同的方式来存储小数,称为CGFloat。幸运的是,Swift 允许我们在任何需要CGFloat的地方使用常规的Double数,所以尽管你有时会看到CGFloat,但你可以忽略它。
如果你好奇的话,浮点数复杂的原因是计算机试图使用二进制来存储复杂的数字。例如,我们知道 1 除以 3 会得到 1/3,但这在二进制中无法存储,所以系统被设计成创建非常接近的近似值。这种方式效率极高,而且误差非常小,通常无关紧要,但至少你知道了为什么 Swift 不允许我们意外地混合使用Int和Double了!
【可选阅读】为什么 Swift 既需要 Double 又需要 Int?
作者:Paul Hudson 2020 年 7 月 19 日 已针对 Xcode 16.4 更新
Swift 为我们提供了几种在代码中存储数字的不同方式,它们旨在解决不同的问题。Swift 不允许我们将它们混合使用,因为这样做肯定会导致问题。
你将使用的两种主要数字类型称为整数(integers)和双精度浮点数(doubles)。整数存储整数,例如 0、1、-100 和 6500 万,而双精度浮点数存储小数,例如 0.1、-1.001 和 3.141592654。
创建数字变量时,Swift 会根据你是否包含小数点来决定将其视为整数还是双精度浮点数。例如:
var myInt = 1
var myDouble = 1.0如你所见,它们都包含数字 1,但前者是整数,后者是双精度浮点数。
现在,既然它们都包含数字 1,你可能会想为什么我们不能把它们相加 —— 为什么我们不能写var total = myInt + myDouble?答案是 Swift 在谨慎行事:我们都知道 1 加 1.0 等于 2,但你的双精度浮点数是一个变量,所以它可能会被修改为 1.1、3.5 或其他值。Swift 怎么能确定将整数与双精度浮点数相加是安全的呢 —— 它怎么能确定你不会丢失 0.1 或 0.5 这样的小数部分呢?
答案是它无法确定这是安全的,这就是为什么不允许这样做。一开始你可能会觉得很麻烦,但相信我:这是有帮助的。
【可选阅读】为什么 Swift 是一种类型安全的语言?
作者:Paul Hudson 2020 年 5 月 29 日 已针对 Xcode 16.4 更新
Swift 允许我们创建字符串、整数等类型的变量,也可以创建许多其他类型的数据变量。当你创建一个变量时,Swift 可以根据你赋给它的数据类型来确定该变量的类型,从那以后,这个变量将始终是那种特定的类型。
例如,下面创建了一个名为meaningOfLife、值为 42 的新变量:
var meaningOfLife = 42因为我们给meaningOfLife赋的初始值是 42,所以 Swift 会将它指定为整数类型 —— 一种整数。它是一个变量,这意味着我们可以根据需要经常更改它的值,但我们不能更改它的类型:它将始终是一个整数。
这在构建应用程序时非常有帮助,因为这意味着 Swift 会确保我们不会在数据上犯错误。例如,我们不能这样写:
meaningOfLife = "Forty two"这试图将一个字符串赋给一个整数类型的变量,这是不允许的。虽然我们很少犯这种明显的错误,但你会发现这种类型安全在你编写 Swift 代码的每一天都能帮上忙。
想想看:我们只是创建了一个变量,然后试图改变它的类型,这显然会失败。但随着你的程序规模和复杂度的增长,你不可能时刻记住所有变量的类型,所以实际上我们是把这项工作交给了 Swift。
恭喜你完成了第一天的学习!是的,这只是第一天,但现在你获得的动力越多,当事情变得更困难时,你就越能坚持下去!