一个下午让你掌握Swift基础 ( 2/9 ) 变量 & 常量

简介

这是一个Swift语言教程,基于最新的iOS 9,Xcode 7.3和Swift 2.2,会为你介绍Swift编程非常基础的内容。从电脑如何工作的全程基本原理到语言结构,你会足够了解这门语言,来处理数据和管理代码的行为。

快速链接


打开Xcode,为你自己创建一个最原始的playground,命名为Tutorial2使用iOS平台。把它保存在硬盘的某个位置,然后准备好开始今天的教程吧!

变量 & 常量

现在你知道了电脑是如何理解你写的代码的,也知道了该用什么工具来写它,所以是时候开始学习Swift本身了。

这篇文章里,你会发现常量(constant)、变量(variable)、类型(type)和元组(tuples),学习怎么声明他们、命名他们和改变他们。也会学习关于类型推断(type inference),Swift最重要的特色之一,是一个会让你的编程生涯变得简单许多的特色。

命名数据

最简单的电脑编程就只是有关操作数据的。记住,你在屏幕上看到的所有东西最后都会变成数字,你发送给CPU的数字。有些时候你自己会和不同类型的数字数据打交道,但其他时候数据会表现成一种更复杂的形式,例如文本(text)、图像和集合(collections)。

在你的Swift代码里,你可以给数据的每一小块一个名字,稍后用来指向它。这个名字带有一个相关类型,类型表示这个名字指向的是哪种数据:文本、数字、日期还是什么其他的。

你在这篇文章会学到一些基本类型,还有许多其他类型会在剩余的教程里穿插。

常量

看看,这是教程里出现的第一次Swift:

let number: Int = 10

这声明了一个常量,叫做number,是Int类型的。然后把这个常量的值设置为数字10。

Int类型可以保存整数——就是数字啦。它被限制只能存储整数,所以另有一种形式来保存小数。例如:

let pi: Double = 3.14159

这和Int常量很相似,除了名字和类型不同。这次常量是Double类型的,可以存储高保真的小数,也就是能够存储的小数位数很多。

也有一个类型叫Float,floating point(浮点)的缩写,也是保存小数,但比Double要低保真。一个Float数字占用的内存比Double要少,但讲道理,数字用的内存根本不是一个大问题,你会看到大部分地方用的都是Double。

声明好一个常量后,就不能改变它的数据了。例如下面的代码:

let number: Int = 10 number = 0

这个代码会产生一个error(错误):

Cannot asign to value: 'number' is a 'let' constant(无法分配值,'number'是一个'let'常量)

在Xcode里,你会看到error这样显示:

常量对于不会改变的值来说很有用处。如果你在做一个模型飞机,需要保持追踪所有可用座位的个数,你就要用常量。

常量也可以用作一个人的年龄。尽管年龄会随着生日到来而改变,但你应该只会关心他在这个特定时刻的年龄。

变量

有时候你想改变名字后面代表的数据。例如,如果你想追踪银行账户的存款和取款,你更应该用变量而不是一个常量。

如果你的程序数据从不改变,那肯定是一个无聊的程序!但你已经看到了,改变常量后面的数据是不可能的。

当你知道你需要改变一些数据的时候,就应该用变量来表示那个数据,而不是常量。用相似的方式来声明变量,像这样:

var variableNumber: Int = 42

只有状态的第一部分有所不同:用let声明常量,而用var声明变量。

声明好变量之后,想怎么改变它都可以,只要类型仍然是相同的就可以。例如,要改变生面声明的变量,可以这样做:

var variableNumber: Int = 42 variableNumber = 0 variableNumber = 1_000_000

要改变变量,简单地设置它和一个新值相等。

注意:Swift里,可以选择性地使用下划线来让大数字看起来更可读。下划线的数量和位置由你来定。

是时候介绍playground的结果边栏了。当你把上面的代码输入到playground里后,你会看到右侧的结果边栏在每一行显示variableNumber的当前值:

结果边栏会在每一行显示一个相关结果,如果存在的话。在变量或常量的例子里,结果会是新的值,不论你是刚刚声明了一个常量,还是声明或重新赋值了一个变量。

命名

总是要尝试为变量和常量选择有意义的名字。

好的名字能特别描述出变量或常量代表什么。这是一些好名字的例子:

  • personAge
  • numberOfPeople
  • gradePointAverage

坏名字通常是因为描述性不够。这是一些坏名字的例子:

  • a
  • temp
  • average

秘诀就是确保你后面再读它的时候还能理解变量或常量指的是什么。不要错以为你有绝对可靠的记忆!在电脑编程里早的话在一两天后回看代码就忘记了它是做什么的是很平常的。通过给变量和常量简便的、清晰的名字会让自己更好过一点。

在Swift里,你甚至能用全部Unicode字符。这意味着你能像这样声明变量:

var 🐶💩: Int = -1

这看起来可能很好笑,但用这样的特殊字符的时候还是要慎重。他们输入起来很困难,因此可能会导致更多的痛苦而不是快乐。

像这样的特殊字符在存储的数据里可能比在Swift代码里会更有意义;你在第4篇教程里会学习到更多关于Unicode的内容,“字符串。”

类型转换

有时候你的数据是一种格式,但需要转换到另一种格式。天真的办法就是这样做:

var integer: Int = 100 var decimal: Double = 12.5 integer = decimal

如果你真的这么做了Swift会抱怨然后在第三行抛出一个错误:

Cannot assign a value of type 'Double' to a value of type 'Int'(不能把一个‘Double’值分配给'Int'类型)

有一些编程语言不像这么严格,会自动实施简单的数字转换,就像你刚刚做的这样。然而,Swift是一门对类型要求非常严格的语言,不允许你分配一个类型的值给另一个类型的变量。

记住,电脑依赖咱们程序员来告诉他们该干嘛。Swift里,那就包括详细表述类型转换。如果你想让转换发生,就需要说出来!

不是简单地赋值,而是需要明确说明你想转换类型。要像这样做:

var integer: Int = 100 var decimal: Double = 12.5 integer = Int(decimal)

第三行的赋值毫不含糊地告诉Swift你想从初始类型,Double,转换到新的类型,Int。

注意:这个例子里,分配小数值给整数结果会导致损失精度:整数变量最终值是12而不是12.5。这就是为什么显示转换类型是这么重要。Swift希望确保你了解你在做什么,因为实施类型转换是可能会导致丢失数据的。

迷你练习

如果你没有在Xcode里跟着做完这些代码,现在是时候创建一个新的playground然后尝试几个练习来测试一下自己了!

  1. 声明一个叫做myAge的Int类型的常量,然后把它设置为你的年龄。
  2. 声明一个叫做averageAge的Double类型变量。刚开始,把它设置为myAge;你会需要用显示类型转换来完成这个操作。然后,设置它为你的年龄和我自己的年龄23的平均值。只需要在脑中做这个计算就可以了——你会在接下来的教程里用Swift来做!

元组

有时候数据是一对一对的,或是个三胞胎。例如2D坐标系里的一对(x,y)坐标。相似的,一组3D坐标系的坐标由x值、y值和z值构成。

Swift里,你可以用一种很简单的方式来表示像这样相关的数据,那就是使用元组

元组是表示任何类型由不止一个值组成的数据类型。元组里你想有多少个值就可以有多少个值。举个例子,你可以定义一对每个坐标轴的值都是整数的2D坐标,像这样:

let coordinates: (Int, Int) = (2, 3)

coordinates的类型是一个元组,包含两个Int值。元组里的值的类型,在这个情况里是Int,被逗号间隔,用括号包围。创建元组的代码都是一样的,每个值被逗号间隔,最外侧被括号包围。

相似的创建Double值的元组很简单,像这样:

let coordinates: (Double, Double) = (2.1, 3.5)

你也可以混合然后匹配类型来组成元组,像这样:

let coordinates: (Double, Int) = (2.1, 3)

这是访问元组里数据的方式:

let coordinates: (Int, Int) = (2, 3) let x: Int = coordinates.0 let y: Int = coordinates.1

你可以用编号提及元组的每个项目,通过它在元组里的位置,从零开始。所以这个例子里,x会等于2,y会等于3。

注意:从零开始是电脑编程里的惯例,叫做零索引(zero indexing)。你会在第10篇教程里再次看到,“数组”。

在前一个例子里,第一个值,在0位置,是x坐标,第二个值,在1位置,是y坐标,看起来都不那么直观。这又一次说明总是用避免误解的方式来命名变量是多么重要。

还好,Swift可以单独命名元组的部分,这样就能明确知道每部分代表什么了。举个例子:

let coordinatesNamed: (x: Int, y: Int) = (2, 3)

这里代码标注出了coordinatesNamed的类型,要为元组的每个部分包含一个标签。

然后,当你需要访问元组的各个部分的时候,你可以通过它的名字来访问:

let x: Int = coordinatesNamed.x let y: Int = coordinatesNamed.y

这样就很清楚了,理解起来也很简单。往往命名元组组成部分比不命名要更有帮助。

如果你一次想访问元组的多个部分,比如在上面的例子里,你也可以使用简写句法来更轻松地实现:

let coordinates3D: (x: Int, y: Int, z: Int) = (2, 3, 1) let (x, y, z) = coordinates3D

这样声明了三个新常量,x,y和z,并且按顺序分配元组里的值给他们。代码和下面的等效:

let coordinates3D: (x: Int, y: Int, z: Int) = (2, 3, 1) let x = coordinates3D.x let y = coordinates3D.y let z = coordinates3D.z

如果你想忽略元组中一个确定的元素,你可以替换相应的声明部分为下划线。例如,你如果你在做2D计算,所以希望忽略3D坐标系里的z坐标,所以你可以这么写:

let (x, y, _) = coordinates3D

这行代码只声明了x和y。_是特定的,简单的代表你现在要忽略这部分了。

注意:你会发现整个Swift中都可以用下划线来忽略一个值。

迷你练习

  1. 声明一个常量元组,包含三个Int值以及一个Double值。用这个来代表日期(月,日,年)以及那个日期的平均温度。
  2. 改变元组来命名组成部分。给他们和包含的数据相关的名字:month, day, year以及averageTemerature。
  3. 在一行里读取day和平均温度到两个常量里。你要用下划线来忽略month和year。
  4. 直到现在,你只见过常量元组。但你也可以创建变量元组。把在上面练习里创建的元组改为变量,通过使用var而不是let。现在改变平均温度到一个新的值。

类型推断

每次你看到变量或常量被声明,都会有一个关联类型。直到你看见从元组中一次读取多个值的语法才没有。再看一下:

let coordinates3D: (x: Int, y: Int, z: Int) = (2, 3, 1) let (x, y, z) = coordinates3D

第二行没有东西来指明x, y和z是Int类型的。所以Swift是怎么知道他们是Int类型的呢?

自己读读代码,很明显第二行创建的常量都是Int类型的。因为代码声明了由三个Int值组成的元组。

这说明了Swift编译器也可以通过推理完成这个过程。不需要你告诉它类型——它自己能搞明白。机智!:]

除了元组的其他地方也可以丢掉类型,同样能够发生这一切。事实上,大部分情况下你都可以删掉类型因为Swift已经知道了。

例如,看一下下面的常量声明:

let typeInferredInt = 42

右手边的值是一个整数类型。Swift也知道,所以它推断这个常量的类型应该是Int。这个过程被认为是类型推断(type inference),并且这是Swift作为一门语言的关键要素。

有时候检查变量或常量被推断的类型是有用的。在playground里按住Option键然后点击变量或常量的名字就可以了。Xcode会像这样显示一个弹窗:

Xcode通过给你如果类型推断的情况下你可能需要用到的声明语句来告诉你推断的类型。在这个例子了,类型就是Int。

其他类型也适用:

let typeInferredDouble = 3.14159

从这里能看出类型推断不是什么魔法。Swift只是单纯做了人类大脑做起来非常简单的事情。不使用类型推断的编程语言通常会让人感觉很啰嗦,因为你每次都要很明显的指出类型,当你在声明变量或常量的时候。

注意:在后面的教程里,你会学习到更复杂的类型,有时候Swift就不能推断出类型了。尽管这是非常罕见的情况,你会看到本教程中大部分代码范例都用了类型推断,除了我想为你特别指明这个类型。

迷你练习

  • 创建一个常量元组包含两个整数但不要写类型。按住Option单击检查类型到底是不是(Int, Int)。
  • 读取上面创建的元组的第一个值到另一个常量里。再次不要写新的常量的类型。再按住Option点击查看常量的类型是不是Int。

关键点

  • 常量和变量给了数据名字。
  • 当你声明好常量后,就不能改变它的数据了,但你能在任何时间改变变量的数据。
  • 总是给变量和常量有意义的名字来避免自己和同事将来会头疼。
  • 可以使用元组把一组数据变成一个单独的数据类型。
  • 类型推断可以让你在Swift已经知道它的类型的情况下不用具体写出类型。

接下来去哪儿?

现在你已经知道了变量和常量,是时候关注一下它们存储在那里的数据了。在接下来两篇文章里,你会学习到最通用的一些数据类型——字符串和数字——以及你能对他们做点什么。

挑战

在结束之前,这是给你测试变量和常量知识的一些挑战。你可以在playground里尝试打出代码来检查你的答案。

A挑战:你就是编译器

下面哪个部分的代码是有效的?

//1 var age = 25 age = 30

//2 let age = 25 age = 30

这是有效的代码吗?

let tuple: (day: Int, month: Int, year: Int) = (15, 8, 2015) let day = tuple.Day

B挑战:输出结果预言家

叫value的那个常量的类型是什么?

let tuple = (100, 1.5, 10) let value = tuple.1

叫month的常量的值是什么?

let tuple: (day: Int, month: Int, year: Int) = (15, 8, 2015) let month = tuple.month


介绍

欢迎来到Swift世界!Swift是一门苹果在2014年夏天发布的编程语言。从那之后,Swift发布了一个主要的版本跳跃,成为了开始在苹果平台:iOS,OS X,watchOS和tvOS开发的最简单的方式。

谁适合这篇教程

这篇教程适合懂一点编程、并且希望学习Swift的人。也许你已经为网站写过一些JavaScript代码,或者用Python写过一些简短的程序。这篇教程就是为你准备的!你会学习到编程的基本概念,同时也会成为Swift语言小能手。

如果你是赤裸裸的编程新手,这篇教程也是为你准备的!教程里贯穿有简短的锻炼和挑战来给你一些编程练习,同时测试你的知识。

需要准备什么

要看这篇教程,你需要准备如下的东西:

  • 一台运行OS X El Captian(10.11)的Mac,带有最新发布的更新并且安装了安全补丁。这样你才能够安装需要的开发工具:最新版本的Xcode。
  • Xcode 7.3或更新的版本。Xcode是用Swift写代码的主要开发工具。最小也需要Xcode 7.3版本,因为那个版本包含Swift 2.2。你可以免费从Mac App Store下载Xcode的最新版本,这里:http://apple.co/1FLn51R

如果你还没有安装Xcode最新版本,在继续看下面的教程前要确定安装。

如何使用这篇教程

每篇教程都会介绍触手可及的话题理论,伴随大量Swift代码来示范在学习的实际的应用程序。

教程里的所有代码都是平台中立的;这意味着不是为iOS、OS X或任何其它平台而特定。代码在playgrounds里运行,你在本篇中已经学习了。

在剩下的教程里,你可以把代码在自己的playground里输入进去。这样你就可以和代码“玩耍”(play around),做一些改变立即就能看见代码运行的结果。

剩下的教程里会贯穿实际小练习,都是简短的练习,关于触手可及的主题。每篇的末尾也有挑战,会有编程问题也会有长一点的代码练习来测试你的知识。做完就能掌握大部分的Swift基础知识。

教程更新

教程会随Swift语言的更新而更新,会发布在我的简书和知乎专栏上,搜索“张嘉夫”即可关注我。

目录

本教程从一些基础工作开始来让你起步:

  • 第1篇,编程本质 & Playground基础 - 这就是,到编程世界的入门介绍!你会从电脑和编程的预览开始,然后剩余时间给Swift playground打个招呼。
  • 第2篇,变量 & 常量 - 你会学习到变量和常量,这是用来存储数据的“地方”。你也会学习数据类型以及Swift如何追踪数据类型并在代码中进行传输。
  • 第3篇,数字类型 & 操作 - 你会从基础的数字类型比如整形和浮点型数字开始,当然也包括布尔类型。也会看到一些在实际操作,从比较到算数操作如加减。
  • 第4篇,字符串 - 用字符串来存储文字-从按钮里的文字到图片的标注到这篇教程全部的文字,存储这所有的一切!你会学习到string和character类型,以及基于这些类型的一些常见操作。

在脑海中有基础数据类型后,就该用那些数据做一些事情了:

  • 第5篇,做判断 - 代码不总是直接从头运行到尾。你会学习在代码里如何做判决并且设定情况来运行某段代码。
  • 第6篇,重复步骤 - 继续不要让代码直线运行的主题,你会学习到如何使用循环来重复某些步骤。
  • 第7篇,函数 - 函数是Swift中用来构建代码的基础建筑。你会学习到如何定义函数来分组代码到可复用单元中。
  • 第8篇,闭包(Closures) - 闭包和函数很接近。你会学习到如何使用它们来轻松传递代码块。

最后一篇会回到数据:

  • 第9节,可选值 - 这篇讲可选值,Swift中的一种特殊类型,表示既有可能是一个真实的值也有可能没有值。这篇的最后你会知道为什么要用可选值以及如何安全地使用它们。

这些基础会让你快速开始Swift之路,做好接触更高级编程主题的准备。

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

推荐阅读更多精彩内容