您现在的位置是:首页 > 文章详情

《Swift入门经典(第2版)》——2.3 数据类型简介

日期:2017-05-01点击:290

本节书摘来自异步社区《Swift入门经典(第2版)》一书中的第2章,第2.3节,作者:【美】BJ Miller(BJ 米勒)著,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.3 数据类型简介

Swift的主要安全特性之一与处理数据类型相关。本节将介绍4种基本的数据类型、它们的组合方式,以及在没有显式指出数据类型时Swift如何推断它们。

2.3.1 类型推断
迄今为止,我们没有显式指出希望Swift为常量和变量使用的数据类型,并且不需要这样做。当没有显式声明数据类型时,Swift将使用所谓的类型推断(type inference)。Swift通过分析设置为常量或变量的值,相应地声明和设置类型。快速查看上一章中的示例,其中把40和2相加。

let myNewValue = 40 + 2
42显然是一个整数,因此Swift推断它是Int类型。在Swift中显式声明常量或变量类型的方式是:给常量或变量名称追加一个冒号(:),其后接着输入类型(比如Int)。这称为类型标注(type annotation)。下面显示了带有类型标注的代码。

let myNewValue: Int = 40 + 2
由于类型推断,将不需要显式指出一种类型,但是这里的示例都比较小。在实际的应用中,在一些情况下,可能出于许多原因将需要声明类型:使得编译器可能为了安全起见而帮助你,作为自文档以清楚查看常量或变量应该保存什么值,或者甚至在函数中指出值的返回类型(第8章将探讨函数)。

2.3.2 数据类型
Swift中相当多的数据类型在你的应用中都可能是有用的。这里将讨论的最常用的数据类型如下。

  • Int:用于整数,它们是没有小数部分的整数。
  • Double和Float:用于浮点数(它们具有小数部分)。
  • String:用于处理字符、文字等的集合。
  • Bool:用于处理真值和假值。

注意:其他数据类型

Swift中许多其他的数据类型可用于进一步细化需要管理的数据的范围。在可能的地方,我们概括了数据类型,以了解与当前数据类型的关系。

警告:数据类型一旦指定将不能改变

一旦把变量或常量声明为特定的数据类型,就不能改变它。此外,在相同的作用域或环境内,还不能利用与现有变量或常量相同的名称来声明新的变量或常量。
1.Int数据类型
整数(integer)是Swift中使用的一种常见数据类型。整数用于统计或枚举有序列表或数组、统计对代码段的特定迭代次数,还包括许多其他实际的应用。如你已经看到的,用于定义整数的关键字就是Int。在32位平台上,Int是32位的整数(或Int32);在64位平台上,Int就是64位的整数(或Int64)。这还是Swift如何保障其数据类型安全的另一个示例。

使用整数的另一种方式是使用无符号整数(unsigned integer)或UInt。无符号整数只是不含负数范围的整数,意味着它们从0开始,上限是你所选的任何整数。Int的最大上限是9×1018和零头,它的下限是−9×1018和零头,因此很有可能永远都不需要一个比它更大的数。更好的例子是UInt8,它是一个8位的整数。Swift提供了8位、16位、32位和64位的UInt版本。继续前进并在下面的“TRY IT YOURSELF”部分学习相关的内容。

TRYITYOURSELF

求整数的最小和最大范围

在Xcode中打开一个playground,并尝试下面的示例。

(1)把一个Int类型的新常量分配给Int.max,你将看到什么值?

let intMax: Int = Int.max
(2)通过UInt8.max和UInt8.min分配新常量。试验另外两个常量:Int8.max和Int8.min。你将看到什么值?

let uint8Max = UInt8.max let uint8Min = UInt8.min let int8Max = Int8.max let int8Min = Int8.min 

(3)为UInt16和UInt32重复执行第(2)步,你将看到什么值?

let uint16Max = UInt16.max let uint32Max = UInt32.max 

(4)现在试验UInt64,你将看到什么?

let uint64Max: UInt64 = UInt64.max
现在可以看到值是18 446 744 073 709 551 615,它是18×1018。

screenshot

完整的“TRY IT YOURSELF”部分应该如图2.1所示。

screenshot

提示:只要有可能,就使用Int

尽管所有这些类型都可供你使用,Apple还是强烈建议只要有可能,就使用Int,即使你可能只需要一个8位的整数,或者只需要正整数(无符号)等。这可以使代码保持一致,并且确保函数和方法与Int返回类型之间具有更好的互操作性,从而避免需要把返回类型强制转换成它们正确的标注。
2.Double数据类型
Double也是在Swift中使用的一种常见数据类型。当需要浮点值或小数值时,就要使用Double。与Double类似的是Float,它们比较相似,但是有如下几个区别需要指出。

Double表示64位的浮点值,Float则表示32位的浮点值。
Double具有至少15个小数位的精度,Float则具有至少6个小数位的精度。
注意:Swift何时推断Double

当对浮点数使用类型推断时,Swift总是优先推断Double,而不是Float。因此,当需要浮点数时,建议总是使用Double,除非处理的是在另一个框架中指定为Float的数字。还值得指出的是:如果代码中的语句涉及对整数和浮点字面量使用算术运算符,则会推断Double返回类型。字面量(literal)是一个值,它以字面意义输入到代码中,作为一个固定的值,比如42、−3.14或“foo”。

注意:整数与浮点数之间的转换

时常,需要把一个类型化的值从一种类型转换成另一种类型,有时将其称为强制类型转换(cast),这是由于将会强制转换变量的类型,使之像另一种兼容的类型那样工作。例如,假定具有一个值为5的Int,并且需要像Double那样处理那个值。由于变量一旦指定,将不能更改它的类型,因此必须声明一个新的变量或常量,使之等于源变量或常量的强制转换的值。考虑下面的示例。

let myInt = 5 //this is inferred to be of type Int let myDouble = Double(myInt)//myDouble is a Double with the value of 5 

可以通过输入类型名称并且用圆括号括住变量或常量,强制转换变量或常量的类型。还可以在把该值与一个不同类型的值相加时,使用变量或常量的强制类型转换,使得Swift创建一个新的变量或常量,它具有与返回值相符合的类型,比如下面的示例。

let myNewDouble = Double(myInt)+ 1.5
由于Double(myInt)和1.5都是Double类型,因此就会推断myNewDouble具有Double类型。对于数值字面量也可以这样做,但是由于字面量直到赋值后才具有类型,因此不需要对它们进行强制类型转换。看看下面这个示例,它把一个整数和一个浮点数相加。

let gravity = 9 + 0.8
在这里,将推断gravity具有Double类型,因为Swift首先处理值(得到9.8),然后把它赋予gravity。
3.Bool数据类型
布尔数据类型比较简单,因为它们只保存逻辑“真”值或“假”值。布尔类型通过Bool关键字标注,它们非常适合于控制应用执行的流程(将在第5章中介绍),以及验证某个条件是true还是false,然后执行特定的代码块。下面给出了一个如何赋予Bool值的清晰示例。

let swiftIsCool = true let objectiveCIsDead = false 

上面的示例把true赋予swiftIsCool,并把false赋予objectiveCIsDead。由于在布尔逻辑中只有true或false值,因此只能赋予这些值。

4.String数据类型
下一个要介绍的数据类型是广泛使用的String数据类型。String是一个合乎逻辑的字符组合,可以猜到,这些字符是Character数据类型。字符串通常输出到控制台上,用作文本框的输入,或者在标签、文本框或扩展的文本视图中输出到屏幕上。

像我们迄今为止讨论过的每一种类型一样,String实际上称为一种结构体(struct)。结构体是一种值类型,它是一种通过添加属性和方法给实体添加功能的结构。你将通过调用Int.max获取Int类型的最大值,对此有一个简单的了解。Int数据类型并不仅仅保存一个数字,它还具有一些属性(比如min和max)以及方法(比如distanceTo(other: Int))。
screenshot

TRYITYOURSELF

查找数据类型上的属性和方法

既然我们知道String、Bool、Int和Double(以及迄今为止讨论过的所有变体)都是结构,就可以轻松查明哪些属性和方法可供每种数据类型使用。

(1)打开Xcode并创建一个playground。Mac或iOS playground都可以。

(2)输入以下代码。

let myInt: Int = 5 let myBool: Bool = true let myString: String = "Hi" let myDouble: Double = 1.5 

(3)按住键盘上的Command键,并单击Int关键字。Xcode将把你带到Int的定义,在那里可以看到,在Swift语言中,如何创建Int,以及在Int结构体和Int的实例上可以使用哪些属性和方法。

(4)单击playground的文本区上方的栏中的Back按钮(一个向左的箭头),返回代码中。按住键盘上的Command键,这一次单击Bool关键字。Xcode将把你带到Bool的定义,在那里可以查看用于Bool类型的属性和方法。

(5)单击playground的文本区上方的栏中的Back按钮,并且为String和Double类型重复执行以前的步骤。在这些数据类型的构造方式以及可以使用什么等方面看到区别了吗?

screenshot

String是一种用于存储Character数据类型的值序列的机制。Character只是在其内存空间中存储的单个字符。这允许我们在Swift中轻松地对字符串做许多事情;可以使用someStringValue.characters.count实例方法轻松地统计String实例中的字符数,它将返回用于表示那个名为someStringValue的String的Unicode字符的数量。我们还可以快速迭代字符串,利用for-in循环中的快速枚举,一次获取一个字符值(第7章将介绍循环)。下面的示例显示了一个字符串以及如何存储它的数据。

let myStr = "Hi!" //myStr contains the following: "H", "i", "!" 

还可以把字符串轻松地连接(或结合)在一起,这与利用“+”运算符把数字相加非常像。在第1章中已经见过了这样一个示例,但是在这里讨论String时值得再次提到它。这是一个强大的特性,可以利用它编写简洁、易读的代码。要连接两个字符串,只需在把它们赋予一个新值时简单地把二者相加,或者把它们一起输出给用户。

let firstString = "Four score" let secondString = "and seven years ago" let newString = firstString + secondString 

newString常量现在包含“Four score and seven years ago”。

由于字符串对于Swift来说是如此基础,因此在创建一些文本以显示给用户或者输出控制台时,现在可以极其轻松地把字符串值以及其他非字符串值插入字符串中,这种方法称为字符串插值(string interpolation)。字符串插值允许在字符串字面量中以内联方式直接插入值,其方法是:按“”(反斜杠)键,然后利用圆括号括住值。下面给出了一个示例。

let year = 2015 let currentYearText = "The current year is \(year)" 

上面代码的输出是一个字符串,其中包含“The current year is 2015”,然后把它设置成常量currentYearText。与Objective-C相比,Apple为Mac和iOS应用选择的语言已经出现差不多30年了,Swift的String实现是梦幻般的。快速看看年代示例在Objective-C中是什么样的。

NSInteger year = 2015; NSString *currentYearText = [NSString stringWithFormat:@"The current year is %d", year]; 

注意:Swift与Objective-C之间的区别

注意,Objective-C中的每条语句都以分号(;)结尾,这指示编译器它到达了语句的末尾。当按Return键时,Swift就推断它是语句的末尾,因此无须显式输入一个分号,尽管也可以这样做。

此外,当使用指针(pointer)时,Objective-C还要依靠程序员使用星号(*)字符。所有的Objective-C对象都是指向堆中内存的指针。Swift不需要使用指针指示符,事实上,你也不会使用它。第10章将进一步讨论Swift中的实例。
在你自己进一步探索这些类型以及可以怎样使用它们之前,还要提到另外几点。Swift允许字符串可变性,只须利用var导引符代替let导引符声明String即可。这样,只须通过把一个String变量设置为另一个String字面量,把一个或多个字符串连接到它,或者把它设置为另一个字符串变量的值,即可更改它的内容。var导引符的可变性并不仅限于String,我只是希望把它用作一个示例。

Swift的String结构体还提供了一个属性isEmpty,它返回一个Bool值。如果需要检查一个String实例中是否具有任何字符,比如在if-else块中,使用这个属性就很方便。

2.3.3 初始化值
Swift要求在使用常量和变量之前声明它们,这意味着使用let或var导引符以及名称和类型声明常量和变量(其中类型是可选的,除非不能推断它或者明确使用类型标注)。还可以立即初始化常量和变量,这样做是很常见的。可以用两种方式执行该操作。第一,可以直接把一个字面量值赋予新的常量或变量;第二,可以使用结构或类的初始化器(initializer)。第13章将更深入地介绍初始化器。下面显示了一些示范性的初始化器的简短示例。

let wheelsOnABicycle = 2 // assigns the numeric literal 2 let wheelsOnATricycle = Int(3) // uses Int's initializer, with the parameter of 3 let emptyString = String() // the empty parentheses indicate an empty String let piVal = Double(3.14) // uses Double's initializer, with the parameter of 3.14 

这些似乎有点多余,因为你可以轻松地输入let piVal = 3.14,代替使用Double的初始化器,但是需要习惯这种语法,以便于学习将来的课程,所以现在值得做出解释。

对于String数据类型,要提及的最后一项是:由于我们发现了如何使用字符串插值以在字符串内使用非字符串值,因此可以在String的实例上使用toInt()方法,把其中只含整数的字符串转换成实际的Int类型。例如:

let degreesOutsideString = "80" //inferred to be a String because of the double-quotes let degreesOutsideInt = Int(degreesOutsideString)! //returns 80 to degreesOutsideInt as an Int 

注意:解包可选值

Swift具有一个称为可选值(optional)的概念,其中的变量可能具有值,也可能没有。在这种情况下,为了保持安全,避免运行时错误,Swift引入了可选值,作为一种在包装器中包装值的方式,以便安全地传递和使用,或者缺少值。上面示例中的感叹号(!)告诉Swift显式解包返回的内容,它来自把字符串转换成整数,因为理论上degreesOutsideString可以具有一个包含任何字符的值,比如度符号或“eighty”,它不能转换成一个整数。第6章将讨论关于可选值的更多知识。

原文链接:https://yq.aliyun.com/articles/98504
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章