Swift语言 快速基础入门 (1)
前端之家收集整理的这篇文章主要介绍了
Swift语言 快速基础入门 (1),
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
(文章出处:http://blog-cn.jiazhewang.com/swift%E8%AF%AD%E8%A8%80-%E5%BF%AB%E9%80%9F%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8/)
本文内容分为两部分,本页是第(1)部分,第二部分请点此浏览:Swift语言 快速基础入门 (2)
快速入门 A Swift Tour
一般来说,我们每学习一种新的编程语言,一上来最经典的上手例子就是 “Hello,world” 。在 Swift 语法中,者只需要一行代码就可以搞定了(而在大部分变成语言中你起码还需要个 main 方法之类的)。【文本代码部分使用 Objective-C 语法高亮,与 Swift 语言略有不同】
|
println
(
"Hello,world"
)
|
如果你学过 C语言或者 Objective-C 的话一定不会对这行代码感到陌生。在 Swift 中,这一行代码就是一个完整的程序了。你不需要再去 import 一些什么东西。(虽然在实际的 Xcode 环境中测试,它可能会默认自动加上一行 import Foundation,但是其实删掉这一行程序也是可以运行的。)全局域中的代码会被自动作为程序的进入点,所以不需要再写什么 main 方法。另外,每一行代码的后边也不再需要加上一个烦人的分号。
简单值 Simple Values
常量与变量
用let来定义常量;常量必须且只能被赋值一次。 用var来定义变量;
|
var
myVariable
=
42
50
let
myConstant
42
|
值的类型
常量或者变量的值的类型必须与被定义的时候的类型一致,但是我们不一定需要把它们的类型写出来。定义常量或变量的时候,编译器会根据我们设置的初始值来推断它们的类型。比如上面的例子中,它们都被推断为整型。 如果初始值不能够提供足够的信息或者初始值缺省,我们可以在变量或常量名后面加一个冒号,然后手动定义它的类型。
|
let
implicitInteger
=
70
implicitDouble
70.0
let
explicitDouble
: Double
70
|
比如上面的例子,explicitDouble 的实际值是70.0而不是70。 Swift 中,值永远不会自动地转化它们的类型,所以如果我们需要转化值的类型,我们必须明确地定义。比如下面例子中的 String(width)把整型的94转化为字符串“94”。
@H_
301_188@
|
let
label
=
"The width is "
width
94
widthLabel
+
String
(
width
)
widthLabel2
// !Could not find an overload for '+' that accepts the supplied arguments
|
另外,有一种更简单的办法,那就是在字符串中直接插入“ \(变量或常量名) ”
apples
3
oranges
5
appleSummary
"I have (apples) apples."
@H_903_ 301@fruitSummary
"I have (apples + oranges) pieces of fruit."
fakeString
(
apples
)
// !Invalid character in source file
|
但是这个方法,\()必须被插入在字符串中,比如”\(varname)”,否则就会出现上面例子中最后一行的错误。
数组与字典
我们可以通过方括号[]来创建数组或者字典,并且通过[序号 index]和[键 key]来访问它们的相应元素。
var
shoppingList
[
"catfish"
,
"water"
"tulips"
"blue paint"
]
shoppingList
[
1
]
"bottle of water"
occupations
[
"Malcolm"
:
"Captain"
Crayon-sy" style="border:0px; font-family:inherit; font-size:inherit!important; font-style:inherit; font-weight:inherit!important; margin:0px; outline:0px; padding:0px; vertical-align:baseline; height:inherit; line-height:inherit!important; color:rgb(51,
"Kaylee"
"Mechanic"
Crayon-sy" style="border:0px; font-family:inherit; font-size:inherit!important; font-style:inherit; font-weight:inherit!important; margin:0px; outline:0px; padding:0px; vertical-align:baseline; height:inherit; line-height:inherit!important; color:rgb(51,
]
occupations
"Jayne"
"Public Relations"
|
当我们需要创建一个空数组或者空字典时,我们可以使用初始化语法,通过添加一个括号()来构造一个相应类型的值。
emptyArray
String
[
]
(
)
emptyDictionary
Dictionary
<
,
Float
>
)
|
当类型可以被编译器推测时,我们也可以直接用一个空方括号[]来表示空数组,以及用[:]来表示空字典。
控制流Control Flow
利用 if 和 switch 语句来实现条件控制,用 for-in,for,while 和 do-while 语句来实现循环控制。
条件语句和循环变量外的小括号()并不是强制的,可有可无。但是包裹内部代码的大括号{}是必须的。
if 语句
individualscores
75
43
103
87
12
]
+=
3
}
else
{
1
}
}
|
在 Playground 中,我们可以看到上述两条条件中的执行语句被可视化。
值得注意的是,在 Swift 语言中,if 语句的条件必须是一个布尔值(Boolean)表达式。也就是说,像 if score {} 这样的语句会被报错,而不会像某些语言那样直接转化成布尔值。相应的功能被转变为通过 if 和 let 的组合来实现,比如下面的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var
optionalString
: String
?
"Hello"
optionalString
==
nil
// false
optionalName1
"John Appleseed"
optionalName2
nil
var
greeting
"Hello!"
if
name
optionalName1
{
"Hello,(name)"
}
// "Hello,John Appleseed"
optionalName2
{
Crayon-line Crayon-striped-line" id=" Crayon-5622f19d94594220007030-14" style=" Box-sizing: border- Box; border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 0px; vertical-align: baseline; height: inherit; font-size: inherit !important; font-weight: inherit !important; padding-left: 10px !important; line-height: inherit !important; white-space: pre-wrap !important; background: rgb(249,(name)"
else
{
Crayon-line Crayon-striped-line" id=" Crayon-5622f19d94594220007030-16" style=" Box-sizing: border- Box; border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 0px; vertical-align: baseline; height: inherit; font-size: inherit !important; font-weight: inherit !important; padding-left: 10px !important; line-height: inherit !important; white-space: pre-wrap !important; background: rgb(249,stranger"
Crayon-sy" style="Box-sizing: border-Box; border: 0px; font-family: inherit; font-size: inherit !important; font-style: inherit; font-weight: inherit !important; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; height: inherit; line-height: inherit !important; color: rgb(51,stranger"
|
可选值
通过 if 和 let 的组合,我们可以处理可能缺失的值。这样的值我们成为可选值(optionals),意为可有可无,不是必须存在的值。一个可选值要么包含一个实际的值,要么用 nil 来表示这个值是缺失的。我们通过在某个值的类型后面添加一个问号来标记它为可选值,就如上面的例子中的那样。(对于给出实际值的可选值,比如 optionalString,Playground 中会给出 {some “Hello”} 这样的提示。)
在上面的例子中,如果可选值(比如 optionalName2)是 nil,那么条件语句的判断结果就是 false,相应括号内的内容就不会被执行了。否则,可选值有实际的值,则可选值被解开并被赋予前面 let 了的常量。这样一来,这个被解开了的值就可以通过这个常量在括号内的执行语句中被调用了。
Switch 语句
在 Swift 语言中,Switch 语句支持各种类型的数据并且提供非常多的比较操作,并不局限于整型和数量测试。(Swift 和 Switch 看起来挺像的哈,会不会苹果是想鼓励大家多用 Switch 呢?开玩笑的啦哈哈)
vegetable
"red pepper"
switch
{
case
"celery"
:
let
vegetableComment
"Add some raisins and make ants on a log."
"cucumber"
"watercress"
:
"That would make a good tea sandwich."
x
where
x
.
hasSuffix
(
"pepper"
)
:
"Is it a spicy (x)?"
default
:
"Everything tastes good in soup."
}
|
上面这个例子非常生动形象地展示了 switch 语句的结构和用法。最终 vegetableComment 的值为 “Is it a spicy red pepper?”。
因为一旦找到了匹配的 case,程序就会运行完这个 case 下面的语句然后跳出 switch,所以根本不需要像 java 之类的语言一样在每一个 case 的执行语句最后都加一个碍眼的 break; Swift 在这方面又提高了语言的简洁度。当然,在所有 case 的最后,default 还是需要加上的,否则会报错。我们知道,算法需要满足可终止性,default 里的内容当所有 case 都无法匹配的时候会被执行。
for-in 循环
我们可以通过 for-in 循环来迭代字典中的项。我们需要设定一组 键-值 (key-value)对应的变量来帮助迭代。比如下面例子中的变量 kind 表示 interestingNumbers 字典的每一个可能的键,numbers 变量则代表对应的值(也就是那些数组)。在内层的 for-in 循环中,number 变量又代表了一个给定数组 numbers 中的每一个可能的元素。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interestingNumbers
[
"Prime"
:
[
2
3
5
7
11
13
Crayon-sy" style="Box-sizing: border-Box; border: 0px; font-family: inherit; font-size: inherit !important; font-style: inherit; font-weight: inherit !important; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; height: inherit; line-height: inherit !important; color: rgb(51,
"Fibonacci"
1
8
Crayon-sy" style="Box-sizing: border-Box; border: 0px; font-family: inherit; font-size: inherit !important; font-style: inherit; font-weight: inherit !important; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; height: inherit; line-height: inherit !important; color: rgb(51,
"Square"
4
9
16
25
Crayon-sy" style="Box-sizing: border-Box; border: 0px; font-family: inherit; font-size: inherit !important; font-style: inherit; font-weight: inherit !important; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; height: inherit; line-height: inherit !important; color: rgb(51,
]
var
largest
0
for
kind
numbers
in
{
for
number
numbers
{
number
>
{
number
}
}
}
largest
|
while 循环
使用 while 语句来执行循环的方式大家也都很熟悉了,执行语句直到条件变更后停止。我们也可以用 do-while 语句来把循环条件放在执行代码的后面,以保证执行代码至少被执行一次。
var
n
2
while
<
100
{
n
*
2
}
n
m
2
do
{
m
2
100
m
为了使条件语句更具有表达性,我们可以加入一个序数(index)。加入序数的方法有两种:一种是
in 初始值..终止值
另一种是 ICI(initialization;condition;increment)也就是
初始值;循环条件;增长量
具体的例子是:
firstForLoop
0
for
i
0..3
{
+=
i
}
firstForLoop
secondForLoop
0
for
var
0
;
<
++
{
1
}
secondForLoop
|
值得注意的是,上面例子中的代码所执行的结果是一模一样的。这是因为 firstForLoop=0+1+2=3。也就是说,第一个循环被执行了三次。其中0,1,2三个值被叠加了。
当我们使用..的时候,末尾的终止值是不被记入循环条件的,也就是相当于 i < 3的结果。而不是小于等于。如果使用…那么终止值被记入循环,相当于小于等于。让我们来看一个具体的比较:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
k1
0
for
i
0..3
{
i
}
// k1 = 0+1+2 = 3
k2
0
0...3
{
i
}
// k2 = 0+1+2+3 = 6
k3
0
0..4
{
i
}
// k3 = 0+1+2+3 = 6
|
函数与闭包 Functions and Closures
func
greet
(
name
Crayon-v" style="Box-sizing: border-Box; border: 0px; font-family: inherit; font-size: inherit !important; font-style: inherit; font-weight: inherit !important; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; height: inherit; line-height: inherit !important; color: rgb(0,
day
@H_763_1 404@->
String
{
return
"Hello (name),today is (day)."
}
(
"Bob"
"Tuesday"
使用func来申明一个函数。之后,通过“函数名(参数1,参数2,..)”的方法来调用函数。 申明函数时,通过在函数参数参数之后使用->后接类型名的方法来申明函数的返回类型。
上面的例子,如果再 Playground 中测试,得到的是”Hello Bob,today is Tuesday.”。函数右边得到的也是这一条,这表示这个函数被调用时的状态。如果调用了两次这个函数,那么 Playground 中此函数右边就会变成(2 times)了,表示被调用的次数。进一步点开后面的圆点后,可以查看具体每一次被调用的状态。
多返回
Swift 中函数也可以返回一组值:
|
func
getGasPrices
(
)
->
(
Double
{
return
(
3.59
3.69
3.79
)
}
)
|
函数也可以以一组不确定个数的值作为参数,把他们作为一个数组来操作:通过(变量名:变量类型…)的方式来声明。
sumOf
numbers
: Int
.
Int
{
sum
0
{
number
}
sum
}
)
(
42
597
12
函数是可以嵌套的。与很多语言不同的是,在 Swift 中,可以直接在函数内部声明新的内函数。内函数可以调用外层函数的变量。
|
@H_ 301_1609@
returnFifteen
Int
{
y
10
add
{
5
}
)
y
}
函数是第一优先级的类型。这意味着一个函数可以返回另一个函数作为自己的返回值。在函数式编程(Functional Programming)中,我们通常称呼这种以另一个函数作为自己的参数或者返回值的函数为高阶函数(Higher Order Function)。这里 Swift 引入了一下函数式编程的概念和方法。
以另一个函数作为返回值的例子:
|
makeIncrementer
(
Int
{
addOne
number
{
1
+
number
}
addOne
}
increment
)
increment
这里(Int->Int)是一个以整型为参数又返回整型的函数。我们假设这样的函数叫 f。那么函数 makeIncrementer()运行之后的结果就是返回函数 f。后面声明的变量 increment 被赋予了函数 makeIncrement()的运行结果,也就是 f。所以,increment 就是函数 f。所以我们在最后可以直接调用 increment(7)来返回一个整型。这里的返回值是8。
下面来看一个以另一个函数作为参数的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
hasAnyMatches
(
list
: Int
[
]
Crayon-sy" style="border:0px; font-family:inherit; font-size:inherit!important; font-style:inherit; font-weight:inherit!important; margin:0px; outline:0px; padding:0px; vertical-align:baseline; height:inherit; line-height:inherit!important; color:rgb(51,
condition
: Int
Bool
Bool
{
item
list
{
condition
item
{
true
}
}
false
}
lessThanTen
number
{
number
10
}
numbers
20
19
7
]
numbers
lessThanTen
这个例子中,函数 hasAnyMatches 旨在判断参数 list 中是否包含满足条件的项,而条件就是另一个参数 condition。但是这里并没有明确这个条件是什么,所以将 condition 声明为一个函数。在实际调用的时候,先写一个条件函数 lessThanTen,然后把它作为参数来调用 hasAnyMatches。
闭包
在 Swift 中我们可以使用闭包。使用 JavaScript 的人对闭包一定不陌生。可以说,函数其实是闭包的一个规定格式的特例。
我们可以写一个闭包来完成函数的工作但是不用给它起名字,只需要吧代码放在一组大括号中间({})。使用关键字in来隔开参数及返回类型的声明和执行代码的部分。比如下面的例子:
|
.
map
{
number
in
result
3
*
number
result
}
这里 numbers 就是上文例子中用到的varnumbers=[20Crayon-sy" style="Box-sizing: border-Box; border: 0px; font-family: inherit; font-size: inherit !important; font-style: inherit; font-weight: inherit !important; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; height: inherit; line-height: inherit !important; color: rgb(51,19712],然后 numbers.map 就是对numbers 这个 list 中的每一项都实行后面的操作。什么操作呢?就像一个函数一样被写在后面的闭包中:获取一个整数,把它乘以3,再返回。
所以我们整段代码得到的结果就是[60,57,21,36]。
闭包甚至可以被写得更加精炼。当一个闭包的类型是已知的,比如一个委托的回调(callback for a delegate),那么可以直接省略掉参数类型或返回类型,或干脆都省略。这样的话闭包会根据默认的方式来返回。比如下面的例子和上例是一样的效果。
|
@H_ 301_1955@
map
{
number
3
}
你也可以使用数字而不是名称来代表参数,这在很短的闭包中非常有用。当一个闭包被当做一个函数的最后一个参数传递时,我们可以直接把它写在函数右小括号后面跟这写,比如下面这个排序:
|