學習之前你要有所準備,它不僅會花費你的一些時間,也許還會花費你的一些錢:

首先

:你需要一個蘋果電腦,MacBook、MacBook Pro、Mac mini都可以,MacBook Air是不行的,記住。如果你買的是iMac、iMac Pro、Mac Pro的話,請務必留下聯絡方式。土豪,我們交個朋友吧!錢能解決的問題都不是問題,記得有錢就買好一點的。如果你現在啥都買不起,哈哈,那你只能等到下一次了,在基於C#開發Micrsoft程式時再見,那個程式也叫“iWriter”。

其次:

你需要安裝Xcode,這個不要錢。聽我的,點選系統左上角“”,選擇下拉選單中“App Store。。。”,在跳出的App Store窗體的左上角里搜尋“Xcode”,找到名為“Xcode”的程式點選“獲取”,等待安裝完成。

這裡,我們即將迎來iWriter的開發之戰。在吹響衝鋒號之前,首先我們需要了解Swift5。1。對,你沒看錯,我們這裡用的是Swift5。1,並會及時使用最新版本。所以你我要同步,因為大部分程式碼都需要你試著執行在Xcode。

來吧,啟動Xcode:開啟Xcode,選擇“Get started with a playground”,選擇“macOS”下的“Blank”,在下一步裡選定儲存位置,就可以了。我們開始鑄造王者之劍。

如果,你有其它程式的開發經驗,瞭解本章你只需要看下面10點。

本章講的是函式程式設計部分。列舉、結構體、類下一章再講。

let宣告常量。

let

π

Double

=

3。14

2。 未賦值不可使用。

var

name

String

// 變數宣告

print

name

// error: variable ‘name’ used before being initialized

3。 使用字串用雙引號或3個雙引號,注意是3個雙引號。

使用3個雙引號包裹字串,能保留字串的格式。如宿進,分行

在使用3個雙引號的方式中,如果某行的行末有“\”符號,那表示下一行與本行是連線在一起的。

字串字面量內,可透過“\(value)”格式插入變數或常量值。類似PHP的$value。

var

str

=

“Jiang Youhua”

var

words

=

“”“

\(

str

is a good person。

He is working very \

hard。

”“”

print

words

// Prints Jiang Youhua is a good person。

// He is working very hard。

var

_

=

3

+

4

//

4。 for 語句不同,使用for-in , 提供“。。。”、“。。<”表示遍歷的範圍。

let

names

=

“Anna”

“Alex”

“Brian”

“Jack”

for

name

in

names

{

// TODO

}

for

i

in

1。

。。

5

{

// TODO

}

for

i

in

stride

from

0

through

12

by

4

{

print

i

}

5。 do-while改為repeat-while。do用在錯誤捕捉上do-catch。

6。 switch語句可以使用範圍,各case預設為break,使用關鍵詞“fallthrough”確定流入下case。

let

score

Int

=

95

switch

a

{

case

100

// TODO

case

95

96

97

98

99

// TODO

case

80。

。<

95

// TODO

case

62。

。<

80

// TODO

case

60

61

// TODO

fallthrough

default

// TODO

}

7。 提供Tuple。訪問Tuple元素,可透過鍵或索引。

let

result

=

“Bad request”

400

// result。0 is ‘Bad request’

let

person

=

name

“JiangYouhua”

gender

true

age

12

// person。age is 12

8。 除Array,Dictionary之外,提供了Set。Set是同類元素的集合,不儲存相同值。

var

threeNumbers

=

1

3

2

// Array

var

aliasesOfCities

Dictionary

=

“昆明”

“春城”

“上海”

“魔都”

,]

// Dictionary

var

subjects

Set

=

“Chinese”

“English”

“Mathematics”

“English”

// Set

print

subjects

// Prints [“English”, “Mathematics”, “Chinese”]

9。 Function保留了Objective-C的特徵,呼叫時需要引數名。但為了與閉包協調,提供添引數別名功能,這時呼叫函式使用的是引數別名。然後又提供“_”符表示匆略,使用它作引數別名,呼叫函式可忽略引數名。

說了那麼多被繞進去了,看程式碼吧

// 函式

func

point

x

Int

y

Int

)->(

String

Bool

){

if

x

<

0

||

y

<

0

{

return

“Err”

false

}

return

“Point。x =

\(

x

, Point。Y =

\(

y

true

}

point

x

100

y

200

//(。0 “Point。x = 100, Point。Y = 200”, 。1 true)

// 引數使用別名

func

pointOfLayout

width

x

Int

height

y

Int

)->(

String

Bool

){

if

x

<

0

||

y

<

0

{

return

“Err”

false

}

return

“Point。x =

\(

x

, Point。Y =

\(

y

true

}

pointOfLayout

width

240

height

160

//(。0 “Point。x = 240, Point。Y = 160”, 。1 true)

// 引數忽略別名

func

pointOfWord

_

x

Int

_

y

Int

)->(

String

Bool

){

if

x

<

0

||

y

<

0

{

return

“Err”

false

}

return

“Point。x =

\(

x

, Point。Y =

\(

y

true

}

pointOfWord

320

129

// (。0 “Point。x = 320, Point。Y = 129”, 。1 true)

// 可變引數

func

income

_

money

Double

。。。){

var

d

=

0。0

for

m

in

money

{

d

+=

m

}

print

“The money added up to

\(

d

}

income

1

2

2

2

5

5

// Prints The money added up to 17。0

10。 閉包、尾隨閉包、閉包轉義。

閉包的格式:{ (parameters) -> return type in statements }

/** 1。 定義一個使用閉包的函式 **/

func

pointOfLayout

point

:(

_

x

UInt32

_

y

UInt32

)->

String

{

let

x

=

arc4random

()

%

1280

let

y

=

arc4random

()

%

960

let

a

=

point

x

y

print

a

}

/** 2。 常規呼叫閉包,參考上面第5點 **/

pointOfLayout

point

{

“point。x =

\(

$0

, point。y =

\(

$1

})

// Prints point。x = 1181, point。y = 382

/** 3。 尾隨呼叫諸包,一種語法糖形式 **/

pointOfLayout

{

“point。x =

\(

$0

, point。y =

\(

$1

}

// Prints point。x = 1101, point。y = 531

/** 4。 當閉包未在函式內呼叫時,需要使用閉包轉義,使用關鍵字:@escaping **/

var

closures

[()

->

Void

=

[]

func

notCalledClosure

closure

@

escaping

()

->

Void

{

closures

append

closure

// 沒有被呼叫,儲存起來了

}

當然,你也可以跟我一起,從零開始,這個就比較長一點。

下面的swift學習教程,是精簡版,是本專案開發中所必需要了解的。如果你想成為Swift的高手,那你需要《葵花寶典》,請上官網查詢:[The Swift Programming Language]。

當你看到這裡,還沒回頭,那表明你需要進一步的學習。所以確認已經打開了你的Xcode,我們將邊做邊學。下面的程式碼你都需要輸入你的Playground裡,執行看看。

滑鼠移到行號上,點選你看到的播放圖示,就可以運行當前行以上的程式碼。

一、註釋:分單行、多行、多行套用三種。

// 這是單行註釋

/*

這是多行註釋的第一行

這是多行註釋的第二行

*/

/* 多行套用註釋,外部

code

/* 多行套用註釋,內部 */

code

多行套用註釋,外部 */

二、關鍵字,請不要使用下列英文單詞作為自已在Swift程式設計中的命名。

與宣告有關:

class,類

deinit,解構函式

enum,列舉

extension,拓展類

func,函式

import。引入模組

init,建構函式

let,常量

protocol,協議

static,靜態

struct,結構體

subscript,下標語法

typealias,類型別名

var 變數

與語句有關:

if else,條件語句

for in where,迴圈語句

repeat while,迴圈語句

switch case default fallthrough,分支語句

do catch,錯誤捕捉

break,退出當前塊

continue,中斷當前流程

return,返回退出當前塊

表示式和型別:

__COLUMN__ ,當前列

__FILE__ ,當前檔名

__FUNCTION__ ,當前方法名

__LINE__ ,當前行

as,型別檢查

dynamicType,已廢除

is,型別檢查

new,無作用

super,指向父類例項

self,指向本類例項

Self,指向本類及其派生類例項

Type,指向本類

在特定上下文中使用:

associativity didSet get infix inout left mutating none nonmutating operator override postfix precedence prefix rightset unowned unowned(safe) unowned(unsafe) weak willSet

三、運算子

算術運算子:加、減、乘、除、求餘。

let

a

=

1

+

2

// 加法運算 a is 3

let

b

=

2

-

1

// 減法運算 b is 1

let

c

=

5

*

2

// 乘法運算 c is 10

let

d

=

5

/

2

// 除法運算 d is 2, 整數相除只保留整數部分

let

e

=

5

%

2

// 求餘運算 e is 1, 求兩個數的餘數

比較運算子:等於、不等於、大於、小於、大於或等於、小於或等於。

let

a

=

1

==

2

// 等於運算,a is false

let

b

=

1

!=

2

// 不等於運算,b is true

let

c

=

1

>

2

// 大於運算,c is false

let

d

=

1

<

2

// 小於運算,d is true

let

e

=

1

>=

2

// 大於或等於運算,e is false

let

f

=

1

<=

2

// 小於或等於運算,f is true

邏輯運算子:邏輯與、邏輯或、邏輯非。

let

a

=

true

&&

false

// 邏輯與運算,a is false

let

b

=

true

||

false

// 邏輯或運算,b is true

let

c

=

true

// 邏輯非運算,c is false

位運算子:按位與、按位或、按位異或、按位反、按位左移、按位右移。

/** 為UInt8新增轉二進位制字串 **/

extension

UInt8

{

// 二進位制String

func

binaryStr

()

->

String

{

// String(number, radix: number), 轉化為幾進位制的字串。

// String(2, radix: 2) 輸出二進位制的 “10“

let

s

=

String

self

radix

2

// 變成10進字面數字。

let

n

=

Int

s

??

0

// 格式化8位輸出。

return

String

format

“Ob%08d”

n

}

}

/** 按位與運算,按位,同1取1,否取0 **/

let

a

UInt8

=

0b11111100

&

0b00111100

print

a

binaryStr

())

// 0b11111100

// 0b00111100

// ——————-

// Prints 0b00111100

/** 按位或運算,按位,有1取1,否取0 **/

let

b

UInt8

=

0b11111100

|

0b00111100

print

b

binaryStr

())

// 0b11111100

// 0b00111100

// ——————-

// Prints 0b11111100

/** 按位異或運算,按位,異取1,同取0 **/

let

c

UInt8

=

0b11111100

^

0b00111100

print

c

binaryStr

())

// 0b11111100

// 0b00111100

// ——————-

// Prints 0b11000000

/** 按位反運算,按位,1轉0,0轉發1 **/

let

d

UInt8

=

~

0b00001111

print

d

binaryStr

())

// 0b00001111

// ——————-

// Prints 0b11110000

/** 按位左移運算,按指定數左移位,右以0補位 **/

let

e

UInt8

=

0b11111100

<<

2

print

e

binaryStr

())

// 0b00111100

// ——————-

// 0b0011110000, 左移後,左溢位,取右邊8位

// Prints 0b11110000

/** 按位左移運算,按指定數右移位,左以0補位 **/

let

f

UInt8

=

0b11111100

>>

2

print

f

binaryStr

())

// 0b00111100

// ——————-

// 0b0011110000, 右移後,右清除,留左邊8位

// Prints 0b00111111

賦值運算。

var

a

Int

=

2

var

b

Int

=

5

b

+=

a

// b = b + a

b

-=

a

// b = b - a

b

*=

a

// b = b * a

b

/=

a

// b = b / a

b

%=

a

// b = b % a

b

&=

a

// b = b & a

b

|=

a

// b = b | a

b

^=

a

// b = b ^ a

b

<<=

a

// b = b << a

b

<<=

a

// b = b >> a

其他運算子。

/** 一元運算子:+、- **/

var

x

=

4

var

y

=

5

print

+

x

-

y

// Prints 4 -5

/** 三元運算子:boolCondition ? a : b **/

var

s

=

x

>

y

“Yes”

“No”

print

s

// Prints No

四、宣告與賦值:let用於常量,var用於變數

常量

:是固定值,程式中不可改,宣告時須賦值。使用let宣告。

變數

:非固定值,程式中可改,未賦值不可用。使用var宣告。

let

π

Double

=

3。14

// 常量

let

e

=

2。718

// 變數

var

city

String

=

“daye”

var

x

y

z

=

100

50

45

var

lastName

firstName

String

lastName

=

“youhua”

firstName

=

“jiang”

五、內建資料型別:整數、浮點數、布林、字元、字串

整數

:有Int、Int8、Int16、Int32、Int64,UInt、UInt8、UInt16、UInt32、UInt64計十類。

其中UInt、UInt8、UInt16、UInt32、UInt64五類為無符號整型。

注意:Int、UInt的長度與系統位數相關,如:64位系統為64位,32位系統為32位。

let

a

=

17

// 十進位制

let

b

=

0b10001

// 二進位制

let

c

=

0o21

// 八進位制

let

d

=

0x11

// 十六進位制

浮點數

:Float、Double。Float為32位,Double為64位。

布林

:只有兩個布林常量,true 和 false。

字元

:單個字元,使用雙引號。

字串

:多個字元,使用雙引號或3個雙引號賦值。

字串:賦值示例。

let

name

String

=

“JiangYouhua”

let

city

String

=

String

“daye”

/** 使用3個雙引號賦值,字串格式將保留 **/

let

poem

=

“”“

床前明月光,疑是地上霜。

舉頭望明月,低頭思故鄉。

”“”

/** 使用3個雙引號賦值,通行尾新增“\”,表示合併下一行 **/

let

proverb

=

“”“

A rolling stone gathers \

no moss。

”“”

// proverb is ‘A rolling stone gathers no moss。’

字串:混合。

/** +、+=, 拼合字串 **/

var

name

String

=

“You”

+

“Hua”

// name is YouHua

name

+=

“ Jiang”

// name is YouHua Jiang

/** \(),將常量、變數新增到字串 **/

let

say

=

\(

name

is good man”

// say is YouHua Jiang is good man

/** %@ 格式化字串 **/

String

format

“String is %@”

“abc”

// s1 is String is abc

/** %d 格式化Int **/

String

format

“Int is %d”

2

// Int is 2

String

format

“Int is %04d”

2

// Int is 0002

/** %f、%g 格式化Double **/

String

format

“Double is %f”

1。1

// Double is 1。100000

String

format

“Double is %0。2f”

1。1

// Double is 1。10

String

format

“Double is %g”

1。1

// Double is 1。1

字串:常用方法。

var

slogan

=

“A rolling stone gathers no moss。”

/** 字串長 **/

var

i

=

slogan

count

// i is 32

/** 字串比較 **/

var

b1

=

slogan

==

“Jiang Youhua”

// b1 is false

/** 字串是否為空 **/

var

b2

=

slogan

isEmpty

// b2 is false

/** 判斷是否包含另一個字串 **/

var

b3

=

slogan

contains

“stone”

// b3 is true

/** 分割 **/

var

words

=

slogan

split

separator

“ ”

// words is [“A”, “rolling”, “stone”, “gathers”, “no”, “moss。”]

/** 合併 **/

var

s1

=

words

joined

separator

“_”

// s1 is A_rolling_stone_gathers_no_moss

/** 獲取指定字元 **/

let

char

=

slogan

slogan

index

slogan

startIndex

offsetBy

8

)]

// char is g

/** 取部分 **/

let

start

=

slogan

index

slogan

startIndex

offsetBy

3

let

end

=

slogan

index

slogan

startIndex

offsetBy

12

let

sub1

=

slogan

start

。。。

end

// sub1 is olling sto

let

sub2

=

slogan

prefix

1

// sub2 is a

let

sub3

=

slogan

suffix

2

// sub3 is s。

/** 查詢位置 **/

let

r

Range

=

slogan

range

of

“no”

let

location

=

slogan

distance

from

slogan

startIndex

to

r

lowerBound

// location is 24

/** 改變大小寫 **/

let

s2

=

slogan

uppercased

()

// s2 is A ROLLING STONE GATHERS NO MOSS。

let

s3

=

slogan

lowercased

()

// s3 is a rolling stone gathers no moss。“

let

s4

=

slogan

capitalized

// s4 is a rolling stone gathers no moss。”

/** 查詢字串 **/

let

s5

=

slogan

replacingOccurrences

of

“。”

with

“!”

// s5 is A rolling stone gathers no moss!“

六、內建集合型別:Tuple元組、Array陣列、Set集合、Dictionary字典。

Tuple,元組是不同資料型別的集合,可透過下標或關鍵字獲取元素。

let

result

=

”Bad request“

400

// result。0 is ‘Bad request’

let

person

=

name

”JiangYouhua“

gender

true

age

12

// person。age is 12

Array,陣列是同類型資料是集合,可透過下標獲取元素。

var

scores

=

Int

]()

// scores is ‘[]’

var

names

String

=

”Jiāngyǒuhuá“

”Lǐbái“

”Dùfǔ“

// names[0] is Jiāngyǒuhuá

var

intTwo

=

Array

repeating

88

count

2

// stringTwo is ‘[88, 88]’

var

threeNumbers

=

1

3

2

// threeNubers[1] is 3

Array:常用方法。

var

scores1

=

1

4

3

5

var

scores2

=

7

3

8

2

/** 合併 **/

var

scoresAll

=

scores1

+

scores1

// scoresAll is [1, 4, 3, 5, 1, 4, 3, 5]

/** 陣列長度 **/

let

i

=

scoresAll

count

// i is 8

/** 陣列是否為空 **/

let

b1

=

scores1

isEmpty

// b1 is false

/** 新增元素 **/

scoresAll

append

9

// scoresAll = [1, 4, 3, 5, 1, 4, 3, 5, 9]

/** 刪除 **/

scoresAll

remove

at

1

print

scoresAll

// Prints [1, 3, 5, 1, 4, 3, 5, 9]

/** 排序 **/

let

a1

=

scoresAll

sorted

by

<

// a3 is [1, 1, 3, 3, 4, 5, 5, 9]

/** 過濾 **/

let

a2

=

scoresAll

filter

{

$0

>

4

}

print

a2

// Prints [5, 5, 9]

/** 包含 **/

let

b2

=

scoresAll

contains

4

// b2 is true

Set,集合同類型資料的集合:無序,無索引,同值元素只保留一個。

var

names

=

Set

<

String

>()

// names is ‘[]’

var

heights

Set

<

Double

>

=

175。5

164。8

180。2

var

subjects

Set

=

”Chinese“

”English“

”Mathematics“

”English“

// subjects is ‘[”English“, ”Mathematics“, ”Chinese“] ’

Set:常用方法。

var

scores1

Set

=

11

4

3

0

5

8

var

scores2

Set

=

4

3

5

var

scoresUni

=

scores1

union

scores2

// scoresUni is [1, 0, 5, 8, 4, 3]

var

scoresInt

=

scores1

intersection

scores2

// scoresInt is [3, 5, 4}]

var

scoresSub

=

scores1

subtracting

scores2

//scoresSub is [11, 8, 0]

var

scoresDif

=

scores1

symmetricDifference

scores2

// scoresDif is [11, 8, 0]

/** 陣列長度 **/

let

i

=

scores1

count

// i is 6

/** 陣列是否為空 **/

let

b1

=

scores1

isEmpty

// b1 is false

/** 新增元素 **/

scoresUni

insert

9

print

scoresUni

// Prints [4, 9, 5, 8, 11, 0, 3]

/** 刪除 **/

scoresUni

remove

1

print

scoresUni

// Prints ”[4, 9, 5, 8, 11, 0, 3]

/** 排序 **/

let

a1

=

scoresUni

sorted

by

<

// a3 is [0, 3, 4, 5, 8, 9, 11]

/** 過濾 **/

let

a2

=

scoresUni

filter

{

$0

>

4

}

print

a2

// Prints [5, 5, 9]

/** 比較 **/

let

b2

=

scores1

==

scores2

// 是否完全相同 b2 is false

let

b3

=

scores1

isSubset

of

scores2

// 1是否為2的子集 b3 is false

let

b4

=

scores1

isSuperset

of

scores2

// 1是否為2的父集 b4 is true

let

b5

=

scores1

isStrictSubset

of

scores2

// 1是否為2的子集並不相等 b5 is false

let

b6

=

scores1

isStrictSuperset

of

scores2

// 1是否為2的父集並不相等 b6 is true

let

b7

=

scores1

isDisjoint

with

scores2

// 是否沒有交集 b7 is false

Dictionary,字典。

var

namesOfUsers

=

Dictionary

<

String

String

>()

// userNames is ‘[:]’

var

argesOfUsers

Dictionary

<

String

Int

>

=

[:]

// userAges is ‘[:]’

var

slogansOfUsers

=

String

String

]()

// userSlogans is ‘[:]’

var

heightsOfNames

Dictionary

<

String

Double

>

=

“Ada”

165。5

“Basia”

182。4

,]

var

aliasesOfCities

Dictionary

=

“昆明”

“春城”

“上海”

“魔都”

,]

Dictionary:常用方法。

var

aliasesOfCities

Dictionary

=

“昆明”

“春城”

“上海”

“魔都”

,]

/** 計數 **/

let

i

=

aliasesOfCities

count

// i is 2

/** 新增 **/

aliasesOfCities

“大冶”

=

“銅都”

print

aliasesOfCities

// Prints [“上海”: “魔都”, “大冶”: “銅都”, “昆明”: “春城”]

/** 刪除 **/

aliasesOfCities

removeValue

forKey

“上海”

print

aliasesOfCities

// Prints [“大冶”: “銅都”, “昆明”: “春城”]

七、控制語句:控制語分迴圈語句、條件語句。

迴圈語句:for-in,while/repeat-while。

條件語句:if/if-else/if-else if-else,switch。

關鍵詞:break,continue。

for-in,迴圈語句。下面示例遍歷陣列、字典、取值範圍、字串。

/** Array **/

let

names

=

“Anna”

“Alex”

“Brian”

“Jack”

for

name

in

names

{

// TODO

}

/** Dictionary **/

let

numberOfLegs

=

“spider”

8

“ant”

6

“cat”

4

for

animalName

legCount

in

numberOfLegs

{

// TODO

}

for

_

legCount

in

numberOfLegs

{

// TODO

}

// 下橫槓符號表示,放棄該值

/** Rang **/

for

i

in

1。

。。

5

{

// TODO

}

for

_

in

-

5。

。。

0

{

// TODO

}

for

i

in

0。

。<

10

{

// TODO

}

for

i

in

stride

from

0

through

12

by

4

{

print

i

}

// Prints 0, 4, 8, 12

/** String **/

let

s

String

=

“JiangYouhua”

for

c

in

s

{

print

c

}

// Prints J, i, a, n, g, Y, o, u, h, u, a

while,repeat-while,迴圈語句。

var

i

=

0

while

i

<

4

{

// TODO

}

repeat

{

// TODO

}

while

i

>

0

if, if-else,if-else if-else,條件語句。

let

score

=

95

if

score

>

60

{

// TODO

}

if

score

>

60

{

// TODO

}

else

{

// TODO

}

if

score

<

60

{

// TODO

}

else

if

score

<

85

{

// TODO

}

else

{

// TODO

}

switch,分支語句。

let

score

=

95

switch

a

{

case

100

// TODO

case

95

96

97

98

99

// TODO 流到該節點

case

80。

。<

95

// TODO

case

65。

。<

80

// TODO

case

60

61

62

63

64

// TODO

fallthrough

default

// TODO

}

continue:中止本次流程。

break:中止區塊內流程。

return:中止區塊內流程,可返回資料。

for

i

in

0。

。。

5

{

if

i

==

3

{

continue

}

print

i

}

// Prints 0, 1, 2, 4, 5

for

i

in

0。

。。

5

{

if

i

==

3

{

break

}

print

i

}

// Prints 0, 1, 2

for

i

in

0。

。。

5

{

if

i

==

3

{

return

}

print

i

}

// Prints 0, 1, 2

八、Function函式:支援多引數、多返回值、引數預設值,提供引數別名、忽略引數名呼叫函式。確立函式的型別

函式的形式,下面羅列了8種

/** 1。 無引數,無返回值 **/

func

helloWorld

(){

print

“Hello, World!”

}

helloWorld

()

// Prints Hello, World!

/** 2。 有引數,無返回值 **/

func

sayHello

name

String

){

print

“Hello,

\(

name

!”

}

sayHello

name

“Jiang”

// Prints Hello, Jiang!

/** 3。 無引數,有返回值 **/

func

averageScoreOfChinese

()->

Double

{

return

89。9

}

print

averageScoreOfChinese

())

// Prints 89。9

/** 4。 多引數,多返回值 **/

func

score

subject

String

student

Int

)->(

String

Double

){

return

“The Score of

\(

subject

of

\(

student

th student is”

99。9

}

var

result

=

score

subject

“English”

student

120

print

result

0

result

1

// Prints The Score of English of 120th student is 99。9

/** 5。 預設引數,命名返回值 **/

func

scoreOther

subject

String

student

Int

=

10

)->(

info

String

score

Double

){

return

“The Score of

\(

subject

of

\(

student

th student is”

99。9

}

var

state

=

scoreOther

subject

“English”

print

state

info

state

score

// Prints The Score of English of 10th student is 99。9

/** 6。 引數別名 **/

func

sayHelloAlias

alias

name

String

{

print

“Hello,

\(

name

!”

}

sayHelloAlias

alias

“Jiang”

// Prints Hello, Jiang!

/** 7。 忽略引數名稱呼叫 **/

func

point

_

x

Int

_

y

Int

){

print

“point。x =

\(

x

, point。y =

\(

y

}

point

100

200

// point。x = 100, point。y = 200

/** 8。 可變引數 **/

func

incomeOfUser

_

name

String

_

income

Double

。。。){

var

f

=

0。00

for

i

in

income

{

f

+=

i

}

print

\(

name

has a total income of

\(

f

}

incomeOfUser

“Jiang”

100。00

360。00

80。50

// Prints Jiang has a total income of 540。5

函式型別

:函式的引數和返回資料的型別都相同的函式,為同一型別的函式。

忽略引數名稱的函式,可以作變數值、引數、返回值。

/** 1。 定義函式 **/

func

point

_

x

Int

_

y

Int

->

Bool

{

print

“point。x =

\(

x

, point。y =

\(

y

return

true

}

/** 2。 函式作為變數值 **/

var

aPoint

:(

Int

Int

)->

Bool

=

point

aPoint

100

90

// Prints point。x = 100, point。y = 90

var

iPoint

=

point

iPoint

200

230

// Prints point。x = 200, point。y = 230

/** 3。 函式作為引數值 **/

func

pointOfLayout

point

:(

Int

Int

)->

Bool

width

Int

height

Int

){

point

width

height

}

pointOfLayout

point

aPoint

width

360

height

240

// Prints point。x = 360, point。y = 240

/** 4。 函式作為返回值 **/

func

xAxle

_

i

Int

)->

String

{

return

“point。x =

\(

i

}

func

yAxle

_

i

Int

)->

String

{

return

“point。y =

\(

i

}

func

axle

b

Bool

)->(

Int

)->

String

{

return

b

xAxle

yAxle

}

var

f

=

axle

b

false

print

f

100

))

// Prints point。y = 100

九、Closure閉包:可以看成加了語法糖的函式。格式 { (parameters) -> return type in statements }

閉包及其幾種簡用方式。

/***

sorted(by:)方法是Swift基本庫的方法,用來對集合型別的資料進行排序,如陣列。

sorted(by:)的作用:對已知型別的陣列進行排序。

sorted(by:)的引數:(String, String) -> Bool。

下面對字串陣列進行排序,以說明閉包的幾種應用形式

***/

/** 1。 使用函式 **/

func

backward

_

s1

String

_

s2

String

->

Bool

{

return

s1

>

s2

}

let

a

=

names

sorted

by

backward

print

“1。 ”

a

// Prints [“Ewa”, “Daniella”, “Chris”, “Barry”, “Alex”]

/** 2。 使用閉包,閉包型別與引數型別相同 **/

let

b

=

names

sorted

by

:{(

s1

String

s2

String

->

Bool

in

return

s1

>

s2

})

print

“2。 ”

b

// Prints [“Ewa”, “Daniella”, “Chris”, “Barry”, “Alex”]

/** 3。 使用閉包,可從上下文推斷其引數與返回資料的型別,所以可最佳化為 **/

let

c

=

names

sorted

by

:{

s1

s2

in

return

s1

>

s2

})

print

“3。 ”

c

// Prints [“Ewa”, “Daniella”, “Chris”, “Barry”, “Alex”]

/** 4。 使用閉包,因閉包只含單條語句,則可省掉“return”,所以可最佳化為 **/

let

d

=

names

sorted

by

:{

s1

s2

in

s1

>

s2

})

print

“4。 ”

d

// Prints [“Ewa”, “Daniella”, “Chris”, “Barry”, “Alex”]

/** 5。 使用閉包,Swift自動為閉包提供$0,$1,$2之類,表示傳入的引數,所以可以最佳化為 **/

let

e

=

names

sorted

by

:{

$0

>

$1

})

print

“5。 ”

e

// Prints [“Ewa”, “Daniella”, “Chris”, “Barry”, “Alex”]

/** 6。 使用閉包,用這種更短的方式,是基於大於號在木Swift中的定義, **/

/** 它的定義與sorted(by:)的引數型別相同,即比較兩個字串並返回布林值 **/

let

f

=

names

sorted

by

>

print

“6。 ”

f

// Prints [“Ewa”, “Daniella”, “Chris”, “Barry”, “Alex”]

尾隨閉包:一種語法糖。

import

Cocoa

// 使用arc4random(),需要引入Cocoa

/** 1。 定義一個使用閉包的函式 **/

func

pointOfLayout

point

:(

_

x

UInt32

_

y

UInt32

)->

String

{

let

x

=

arc4random

()

%

1280

let

y

=

arc4random

()

%

960

let

a

=

point

x

y

print

a

}

/** 2。 常規呼叫閉包,參考上節第5點 **/

pointOfLayout

point

{

“point。x =

\(

$0

, point。y =

\(

$1

})

// Prints point。x = 1181, point。y = 382

/** 3。 尾隨呼叫諸包,一種語法糖形式 **/

pointOfLayout

{

“point。x =

\(

$0

, point。y =

\(

$1

}

// Prints point。x = 1101, point。y = 531

/** 4。 當閉包內含多行語句時,尾隨閉包更具有可讀性 **/

pointOfLayout

{(

_

x

UInt32

_

y

UInt32

)->

String

in

let

a

=

x

*

100

let

b

=

x

*

100

return

“point。x =

\(

a

, point。y =

\(

b

}

// point。x = 89200, point。y = 89200

閉包轉義:閉包在函式內未呼叫,則需要宣告轉義 ,使用 @escaping。

var

closures

[()

->

Void

=

[]

/** 閉包沒有在函數里呼叫,只是儲存在數組裡,所以需要轉義 **/

func

notCalledClosure

closure

@

escaping

()

->

Void

{

closures

append

closure

}

/** 閉包在函數里被呼叫,不需要轉義 **/

func

calledClosure

closure

()

->

Void

{

closure

()

}

/** 沒有輸出 **/

notCalledClosure

{

print

100

}

// No output

/** 立即輸出 **/

calledClosure

{

print

200

}

// Prints 200

下一篇,Swift 的進階。

讓我們在這裡,遇見明天的自己!姜友華