Swift语言指南(五)--数字字面量和数字类型转换

时间:2021-06-20 15:34:30

原文:Swift语言指南(五)--数字字面量和数字类型转换

数字字面量

整数字面量写法如下:

· 十进制数,无前缀

· 二进制数,以 0b 为前缀

· 八进制数,以 0o 为前缀

· 十六进制数,以 0x 为前缀

下面所有整数字面量值为十进制的 17 :

 let decimalInteger = 17
let binaryInteger = 0b10001 // 17 二进制标识
let octalInteger = 0o21 // 17 八进制标识
let hexadecimalInteger = 0x11 // 17 十六进制标识

浮点数字面量可以是二进制(无前缀)或十六进制(以 0x 为前缀),小数点的两侧必须有各有一个数字(或十六进制数字)。他们都可以拥有一个可选的指数幂,十进制小数标记为大写或小写的 ,十六进制标记为大写或小写的 p 。

指数幂为 exp 的十进制数字,它的基数将乘以 10exp :

· 1.25e2 表示 1.25 × 102, 或 125.0.
· 1.25e-2 表示 1.25 × 10-2, 或 0.0125.

指数幂为 exp 的十六进制数字,它的基数将乘以 2exp:

· 0xFp2 表示 15 × 22, 或 60.0.
· 0xFp-2 表示 15 × 2-2, 或 3.75.

下面所有浮点数的字面值为十进制值 12.1875:

 let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0

数字字面量可以包含其它的格式以便于阅读。整数与浮点数均可以添加多余的零或下划线以提高可读性。两种格式均不会影响字面量的实际值:

 let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1

数字类型转换

代码中应使用 Int 类型作为所有常规用途的整数常量及变量的类型,即使它们的确为非负数。日常使用中,使用默认的整数类型意味着这些整型常量与变量均可即时互相参与运算,并可与根据整数字面值推断出的类型相匹配。

仅当手中的任务必须使用其他整数类型时才用它们,如外部数据源提供宽度明确的数据,或为了性能、内存占用等其他必需优化的情况考虑。在这些情况下使用宽度明确的类型有助于发现偶然的数值溢出和捕捉使用时数据的原始信息。

整数转换

不同数字类型所能存储的值域范围是不同的。一个 Int8 常量或变量能存储 -128 到 127 之间的数字,而一个 UInt8 常量或变量能存储 0 到 255 的数字。无法存进一个整型的常量或变量的数字编译时会报错:

 let cannotBeNegative: UInt8 = -1
// UInt8 不能保存负数, 所以这里会报错的
let tooBig: Int8 = Int8.max + 1
// Int8 不能保存超过其最大值范围的数字,
// 所以这里也会报错的

由于不同数据类型能存储的值域不同,在进行数据转换时需要具体问题具体对待。这种实际选择的过程可避免隐式转换的问题,还能在代码中强化类型转换的意图。

要将一个数字的类型转换为另一种,应先把现有值初始化一个所需类型的新的数字。下例中,常量 twoThousand 的类型为 UInt16,而常量 one 的类型为 UInt8。它们无法直接相加,因为类型不同。因此,本例将调用 UInt16(one) 新建一个 UInt16 数,并将 one 的数值初始化,用初始化的新值(新值为 UInt16 )取代原始值(原始值为 UInt8 ):

 let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)//将常量one初始化为UInt16

现在加号两侧均为 UInt16 类型,因此相加合法。输出的常量 (twoThousandAndOne) 的推断类型为 UInt16,因为其为两个 UInt16 值之和。

某些类型(初始值) 是调用 Swift 类型构造函数并传递初始值的默认方法。幕后运作情况是,UInt16 有一个接受 UInt8 值的构造函数,因此该构造函数会被用于根据现有 UInt8 创建新的 UInt16。不过,在这里并不能传入任意类型——只能传入 UInt16 提供有构造函数的类型。扩展现有类型使其提供接受新类型(包括自己定义的类型)的构造函数的方法请见 扩展 (后面会译到)一章。

整数和浮点数间的转换

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

 let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
// pi 等于 3.14159, 故而推断类型为Double

在上例中,常量 three 的值被用来创建一个新的 Double 类型,以便加号两侧的类型保持一致,如果类型没有转换,是不允许相加的。

反过来,浮点数到整数的转换同样可行,整数类型可以用 DoubleFloat 值初始化:

 let integerPi = Int(pi)
// integerPi 等于 3, 类型推断为Int

这样用浮点数初始化为新的整数时,浮点数值总会被截断。即, 4.75 变为 4, -3.9 变为 -3。

注意:

数字常量或变量的结合规则与数字字面量的结合规则不同。字面量 3 可以直接与字面量 0.14159 相加,因为数字字面量没有明确指定类型,它们自身也没有明确的类型。其类型仅当被编译器求值时才推断得出。

谢谢,Swifter-QQ群:362232993,同好者进~

Fork:https://github.com/Joejo/Swift-lesson-for-chinese