swift Swift一起修炼swift

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

2016-07-04  本文已影响1142人  张嘉夫

简介

这是一个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的当前值:

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

命名

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

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

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

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

在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就不能推断出类型了。尽管这是非常罕见的情况,你会看到本教程中大部分代码范例都用了类型推断,除了我想为你特别指明这个类型。

迷你练习

关键点

接下来去哪儿?

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

挑战

在结束之前,这是给你测试变量和常量知识的一些挑战。你可以在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语言小能手。

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

需要准备什么

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

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

如何使用这篇教程

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

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

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

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

教程更新

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

目录

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

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

最后一篇会回到数据:

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

上一篇下一篇

猜你喜欢

热点阅读