类型标注
当你声明常量或者变量的时候可以加上类型标注(type annotation),说明常量或者变量中要存储的值的类型。如果要添加类型标注,需要在常量或者变量名后面加上一个冒号和空格,然后加上类型名称。
var welcomeMessage: String
一般来说你很少需要写类型标注。如果你在声明常量或者变量的时候赋了一个初始值,Swift可以推断出这个常量或者变量的类型,请参考类型安全和类型推断。在上面的例子中,没有给welcomeMessage
赋初始值,所以变量welcomeMessage
的类型是通过一个类型标注指定的,而不是通过初始值推断的。
常量和变量的命名
一旦你将常量或者变量声明为确定的类型,你就不能使用相同的名字再次进行声明,或者改变其存储的值的类型。同时,你也不能将常量与变量进行互转。
输出常量和变量
println
是一个用来输出的全局函数,输出的内容会在最后换行。如果你用 Xcode,println
将会输出内容到“console”面板上。(另一种函数叫print
,唯一区别是在输出内容最后不会换行。)
println("This is a string")
// 输出 "This is a string"
Swift 用字符串插值(string interpolation)的方式把常量名或者变量名当做占位符加入到长字符串中,Swift 会用当前常量或变量的值替换这些占位符。将常量或变量名放入圆括号中,并在开括号前使用反斜杠将其转义:
println("The current value of friendlyWelcome is \(friendlyWelcome)")
// 输出 "The current value of friendlyWelcome is Bonjour!
注释
与C 语言多行注释不同,Swift 的多行注释可以嵌套在其它的多行注释之中。你可以先生成一个多行注释块,然后在这个注释块之中再嵌套成第二个多行注释。终止注释时先插入第二个注释块的终止标记,然后再插入第一个注释块的终止标记:
/* 这是第一个多行注释的开头
/* 这是第二个被嵌套的多行注释 */
这是第一个多行注释的结尾 */
通过运用嵌套多行注释,你可以快速方便的注释掉一大段代码,即使这段代码之中已经含有了多行注释块。
分号
与其他大部分编程语言不同,Swift 并不强制要求你在每条语句的结尾处使用分号(;
),当然,你也可以按照你自己的习惯添加分号。有一种情况下必须要用分号,即你打算在同一行内写多条独立的语句:
let cat = "?"; println(cat)
// 输出 "?"
类型安全和类型推测
Swift 是一个类型安全(type safe )的语言。类型安全的语言可以让你清楚地知道代码要处理的值的类型。如果你的代码需要一个String
,你绝对不可能不小心传进去一个Int
。
由于 Swift 是类型安全的,所以它会在编译你的代码时进行类型检查(type checks),并把不匹配的类型标记为错误。这可以让你在开发的时候尽早发现并修复错误。
当你要处理不同类型的值时,类型检查可以帮你避免错误。然而,这并不是说你每次声明常量和变量的时候都需要显式指定类型。如果你没有显式指定类型,Swift 会使用类型推测(type inference)来选择合适的类型。有了类型推测,编译器可以在编译代码的时候自动推测出表达式的类型。原理很简单,只要检查你赋的值即可。
因为有类型推测,和 C 或者 Objective-C 比起来 Swift 很少需要声明类型。常量和变量虽然需要明确类型,但是大部分工作并不需要你自己来完成。
当你声明常量或者变量并赋初值的时候类型推测非常有用。当你在声明常量或者变量的时候赋给它们一个字面量(literal value 或 literal)即可触发类型推测。(字面量就是会直接出现在你代码中的值,比如42
和3.14159
。)
例如,如果你给一个新常量赋值42
并且没有标明类型,Swift 可以推测出常量类型是Int
,因为你给它赋的初始值看起来像一个整数:
let meaningOfLife = 42
// meaningOfLife 会被推测为 Int 类型
同理,如果你没有给浮点字面量标明类型,Swift 会推测你想要的是Double
:
let pi = 3.14159
// pi 会被推测为 Double 类型
当推测浮点数的类型时,Swift 总是会选择Double
而不是Float
。
如果表达式中同时出现了整数和浮点数,会被推测为Double
类型:
let anotherPi = 3 + 0.14159
// anotherPi 会被推测为 Double 类型
原始值3
没有显式声明类型,而表达式中出现了一个浮点字面量,所以表达式会被推测为Double
类型。
整数转换
要将一种数字类型转换成另一种,你要用当前值来初始化一个期望类型的新数字,这个数字的类型就是你的目标类型。在下面的例子中,常量twoThousand
是UInt16
类型,然而常量one
是Uint8
类型。它们不能直接相加,因为它们类型不同。所以要调用UInt16(one)
来创建一个新的UInt16
数字并用one
的值来初始化,然后使用这个新数字来计算:
let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)
布尔值
Swift 有一个基本的布尔(Boolean)类型,叫做Bool
。布尔值指逻辑上的(logical),因为它们只能是真或者假。Swift 有两个布尔常量,true
和false
:
let orangesAreOrange = true
let turnipsAreDelicious = false
元组
元组(tuples)把多个值组合成一个复合值。元组内的值可以使任意类型,并不要求是相同类型。
下面这个例子中,(404, "Not Found")
是一个描述 HTTP 状态码(HTTP status code)的元组。HTTP 状态码是当你请求网页的时候 web 服务器返回的一个特殊值。如果你请求的网页不存在就会返回一个404 Not Found
状态码。
let http404Error = (404, "Not Found")
// http404Error 的类型是 (Int, String),值是 (404, "Not Found")
(404, "Not Found")
元组把一个Int
值和一个String
值组合起来表示 HTTP 状态码的两个部分:一个数字和一个人类可读的描述。这个元组可以被描述为“一个类型为(Int, String)
的元组”。
你可以把任意顺序的类型组合成一个元组,这个元组可以包含所有类型。只要你想,你可以创建一个类型为(Int, Int, Int)
或者(String, Bool)
或者其他任何你想要的组合的元组。
你可以将一个元组的内容分解(decompose)成单独的常量和变量,然后你就可以正常使用它们了:
let (statusCode, statusMessage) = http404Error
println("The status code is \(statusCode)")
// 输出 "The status code is 404"
println("The status message is \(statusMessage)")
// 输出 "The status message is Not Found"
如果你只需要一部分元组值,分解的时候可以把要忽略的部分用下划线(_
)标记:
let (justTheStatusCode, _) = http404Error
println("The status code is \(justTheStatusCode)")
// 输出 "The status code is 404"
此外,你还可以通过下标来访问元组中的单个元素,下标从零开始:
println("The status code is \(http404Error.0)")
// 输出 "The status code is 404"
println("The status message is \(http404Error.1)")
// 输出 "The status message is Not Found"
你可以在定义元组的时候给单个元素命名:
let http200Status = (statusCode: 200, description: "OK")
给元组中的元素命名后,你可以通过名字来获取这些元素的值:
println("The status code is \(http200Status.statusCode)")
// 输出 "The status code is 200"
println("The status message is \(http200Status.description)")
// 输出 "The status message is OK"
作为函数返回值时,元组非常有用。一个用来获取网页的函数可能会返回一个(Int, String)
元组来描述是否获取成功。和只能返回一个类型的值比较起来,一个包含两个不同类型值的元组可以让函数的返回信息更有用。请参考[函数参数与返回值(06_Functions.html#Function_Parameters_and_Return_Values)。
注意:
元组在临时组织值的时候很有用,但是并不适合创建复杂的数据结构。如果你的数据结构并不是临时使用,请使用类或者结构体而不是元组。请参考类和结构体。