《Swift by Tutorials》学习笔记(第一章)
原本已经决定把JavaScript系统学习一遍,却因为各种原因转投到了iOS门下,也导致了我将近两个月的时间没有写博客了。今天开始要把博客重新捡起来了,在现阶段博客的主要内容还是自己的一些学习笔记,因为刚开始学习,没有太多能分享的东西,等到之后如果小有所成,再来写一点类似教程类的博客。
现阶段如果要学iOS都是直接从Swift开始上手了,这门语言是苹果公司现在主推的语言,鉴于苹果公司一贯的激进作风,Swift应该会慢慢取代OC语言成为开发iOS应用的主打语言。Swift语言的语法还是比较简明的,如果有别的程序语言的基础,要上手是非常容易的。
起步
新版的Xcode提供了一个新工具,Playground
,这个工具是用来学习Swift语法的利器。Playground的功能可以相当于Python中的解释器来使用,当你在左边输入一条语句,Playground会自动进行编译和运行,然后在右边的面板中输出语句的结果。
有了如此好用的工具,就可以愉快地开始学习Swift了。
变量、常量和字符串
新建一个Playground
,然后将原来的内容删除,输入如下代码:
var greeting: String = "Hello"
println(greeting)
就可以立即在右边的面板中看到输出了Hello
。这个面板用来快速查看结果很方便,但是如果想要查看完成的控制台输出,可以在菜单View/Assistant Editor/Show Assistant Editor中打开
。
上面的代码中定义了一个变量greeting
,我们可以改变它的值:
var greeting: Stringn = "Hello"
greeting = "Bonjour"
println(greeting)
在Swift当中,还有更方便的方法来声明一个变量:
var greeting = "Hello"
在上面的语句当中,没有指定变量greeting
的类型,但是编译器会根据赋值的内容来自动推断出要声明的变量的类型,这称为 类型推断。
看到这样的语句,很容易让人误以为Swift是弱类型的语言,事实上,Swift是实实在在的强类型语言。像下面的代码在编译期间会报 type 'String' does not conform to protocol 'IntegerLiteralConvertible' 的错误:
var greeting = "Hello"
greeting = 42
println(greeting)
可以直接使用+
号对字符串进行拼接:
var greeting = "Hello"
greeting = greeting + " World"
println(greeting)
Swift当中的字符串默认是可变的,即我们可以改变字符串的值。
上面的代码中声明的都是变量,如果要声明常量,可以使用let
关键字。如果将上面的代码改为
let greeting = "Hello"
...
则会导致编译错误,因为在常量初始化完成之后,就不能再改变它们的值了。
苹果官方建议应尽量使用常量,使用常量可以使代码健壮,同时使编译器对代码进行优化。所以在Swift当中,基本上的使用
let
会比使用var
多。
Swift为字符串提供了少量的操作方法,好在Swift的字符串可以与NSString
进行无缝地切换使用:
import Foundation
var greeting = "hello".stringByAppendingString(" world")
println(greeting)
并且Swift当中的字符串是值类型,也即在对字符串进行赋值的时候,传递的是值,而不是地址,这与许多语言都是不一样的。
...
var alternateGreeting = greeting
alternateGreeting += " and beyond!"
println(alternateGreeting)
println(greeting)
在上面的代码中,因为拷贝的是字符串的值,所以在对alternateGreeting
进行修改的时候,不会影响到原本的greeting
。
分号
在Swift当中,只要当多条语句写在同一行的时候才需要使用分号来分隔,其它情况下都不需要加分号
数值类型与转换
现在来看看Swift当中的数值类型:
var radius = 4
let pi = 3.14159
上面的代码声明了一个Int
型的变量raidus和一个Double
型的常量pi。同样的,我们不需要指定类型,编译器会自己推断出所需要的类型。默认没有指定类型的情况下,编译器对整型和符点型都是使用Int
和Double
。
虽然Swift情况有各种不同范围的整数类型,比如Int8
(8 位有符号整型)和UInt16
(16位无符号整型),同时还有Float
类型的符点类型。但是官方建议在没有特殊要求的情况下尽量使用Int
与Double
。
在定义整型数据的时候,还可以使用千位分隔符,用来增加可读性:
let million = 1_000_000
我们可以使用各种基本的运算符对变量进行操作,但是由于Swift是强类型语言,同时它不允许自动的隐式转换,所以在进行运算的时候可能会碰到坑:
var area = raidus * radius * pi
上面这句会在编译期报错。因为整数与符点数是不同的类型,所以我们不能直接进行运算,而需要这么做:
var area = Double(radius) * Double(radius) * pi
将整型转化成符点型然后再进行计算。要注意我们并不是进行了强制类型转换,而是使用了Double
的构造函数重新构造了一个Double
型的数,然后再进行运算的。
Swift也会对数值的范围进行检测,如果数值的运算超出了数值范围,编译器也会报错。这些都是Swift提供的安全特性。
布尔类型
布尔类型只有两个值,即true
和false
。与OC不同,Swift不会将非零值视为true,也不会将零视为false,它只接受true
与false
两个值。
元组
元组可以用将一些简单的值组成成一种类型。与结构体和类不同,在使用元组的时候,不需要声明一种新的类型,而可以直接使用。
// 声明一个元组,并获取它的值
var address = (742, "Evergreen Terrace")
println(address.0)
pritnln(address.1)
如果我们访问了超出范围的元组索引,也会在编译期造成错误。
可以使用索引来对元组的值进行修改:
// 修改元组的值
address.0 = 744
上面的元组声明中,我们使用了类型推断,我们也可以显式地指定类型,同时还可以对元组进行解包:
// 声明(Int, String)类型的元组
var address: (Int, String) = (742, "Evergreen Terrace")
// 对元组进行解包
let (house, street) = address
println(house)
println(street)
我们还可以对元组的元素进行命名,然后通过名称访问元素:
var address = (number: 742, street: "Evergreen Terrace")
println(address.number)
println(address.street)
字符串插值
有时,需要在字符串当中插入数值类型的值,这时可以使用字符串插值:
var address = (742, "Evergreen Terrace")
let (house, street) = address
let str = "I live at \(house), \(street)"
println(str)
控制流
For 循环
在Swift当中,支持普通的for
循环,同时也支持增强型的for-in
循环。
let greeting = "Swift by Tutorials"
for i in 1...5 {
println("\(i) - \(greeting)")
上面的代码中,1...5
是一个Range
类型的值,三个点代表的是范围包括最后一个数,如果不想包含最后一个数,则可以使用1..<5
。
While 循环
Swift也同时支持while
和do-while
循环。
var i = 0
while i < 5 {
println("\(i) - \(greeting)")
i++
If 语句
Swift支持if
、if/else
和if/else-if/else
类型的控制语句。
let greeting = "Swift by Turtorials"
for i in 1...5 {
if i == 5 {
println(greeting.uppercaseString)
} else {
println(greeting)
}
需要注意的是,在Swift当中,就算执行体只有一条语句,也必须加上花括号。
Swift 语句
Swift中的switch
语句可谓强大。它不仅能够匹配数值类型,还能匹配其它的类型,但是要匹配的类型,与case
中的类型必须要一致,不然会造成错误。
var direction = "up"
switch direction {
case "down":
println("Going down!")
case "up":
println("Going up!")
default:
println("Going Nowhere")
这段代码将会输出Going up
,可以看出在Swift当中,每个case
后面是不需要显式加上break
的。同时,case
中的情况,必须要穷举完要判断的类型的所有情况,否则编译器将会报错。
除了上面这种标准的用法,Swift当中的switch
还有很多其它的灵活的用法。如:
switch direction {
case "down", "up":
println("Going Somewhere!")
default:
println("Going Nowhere")
}
只要direction
是down
或者up
其中之一,则第一个case
就能匹配成功。
还能使用范围值来进行匹配:
var score = 570
switch score {
case 1..<10:
println("novice")
case 10..<100:
println("proficient")
case 100..<100:
println("rock-star")
default:
println("awesome")
}
switch
还有很多其它强大的功能,在后面的章节会讨论。
总结
这章主要讨论了swift中的一些基础数值类型与控制流,除了一些特殊的地方,其它语法都与主流的语言大同小异的。只要有其它语言的背景,上手swift的速度是很快的。