學習之前你要有所準備,它不僅會花費你的一些時間,也許還會花費你的一些錢:
首先
:你需要一個蘋果電腦,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
// 變數宣告
(
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。
”“”
(
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
)
{
(
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
(
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
}
(
“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
)
(
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
(
a
。
binaryStr
())
// 0b11111100
// 0b00111100
// ——————-
// Prints 0b00111100
/** 按位或運算,按位,有1取1,否取0 **/
let
b
:
UInt8
=
0b11111100
|
0b00111100
(
b
。
binaryStr
())
// 0b11111100
// 0b00111100
// ——————-
// Prints 0b11111100
/** 按位異或運算,按位,異取1,同取0 **/
let
c
:
UInt8
=
0b11111100
^
0b00111100
(
c
。
binaryStr
())
// 0b11111100
// 0b00111100
// ——————-
// Prints 0b11000000
/** 按位反運算,按位,1轉0,0轉發1 **/
let
d
:
UInt8
=
~
(
0b00001111
)
(
d
。
binaryStr
())
// 0b00001111
// ——————-
// Prints 0b11110000
/** 按位左移運算,按指定數左移位,右以0補位 **/
let
e
:
UInt8
=
(
0b11111100
)
<<
2
(
e
。
binaryStr
())
// 0b00111100
// ——————-
// 0b0011110000, 左移後,左溢位,取右邊8位
// Prints 0b11110000
/** 按位左移運算,按指定數右移位,左以0補位 **/
let
f
:
UInt8
=
(
0b11111100
)
>>
2
(
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
(
+
x
,
-
y
)
// Prints 4 -5
/** 三元運算子:boolCondition ? a : b **/
var
s
=
x
>
y
?
“Yes”
:
“No”
(
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
)
(
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
}
(
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
)
(
scoresUni
)
// Prints [4, 9, 5, 8, 11, 0, 3]
/** 刪除 **/
scoresUni
。
remove
(
1
)
(
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
}
(
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
[
“大冶”
]
=
“銅都”
(
aliasesOfCities
)
// Prints [“上海”: “魔都”, “大冶”: “銅都”, “昆明”: “春城”]
/** 刪除 **/
aliasesOfCities
。
removeValue
(
forKey
:
“上海”
)
(
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
)
{
(
i
)
}
// Prints 0, 4, 8, 12
/** String **/
let
s
:
String
=
“JiangYouhua”
for
c
in
s
{
(
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
}
(
i
)
}
// Prints 0, 1, 2, 4, 5
for
i
in
0。
。。
5
{
if
i
==
3
{
break
}
(
i
)
}
// Prints 0, 1, 2
for
i
in
0。
。。
5
{
if
i
==
3
{
return
}
(
i
)
}
// Prints 0, 1, 2
八、Function函式:支援多引數、多返回值、引數預設值,提供引數別名、忽略引數名呼叫函式。確立函式的型別
函式的形式,下面羅列了8種
/** 1。 無引數,無返回值 **/
func
helloWorld
(){
(
“Hello, World!”
)
}
helloWorld
()
// Prints Hello, World!
/** 2。 有引數,無返回值 **/
func
sayHello
(
name
:
String
){
(
“Hello,
\(
name
)
!”
)
}
sayHello
(
name
:
“Jiang”
)
// Prints Hello, Jiang!
/** 3。 無引數,有返回值 **/
func
averageScoreOfChinese
()->
Double
{
return
89。9
}
(
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
)
(
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”
)
(
state
。
info
,
state
。
score
)
// Prints The Score of English of 10th student is 99。9
/** 6。 引數別名 **/
func
sayHelloAlias
(
alias
name
:
String
)
{
(
“Hello,
\(
name
)
!”
)
}
sayHelloAlias
(
alias
:
“Jiang”
)
// Prints Hello, Jiang!
/** 7。 忽略引數名稱呼叫 **/
func
point
(
_
x
:
Int
,
_
y
:
Int
){
(
“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
}
(
“
\(
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
{
(
“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
)
(
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
)
(
“1。 ”
,
a
)
// Prints [“Ewa”, “Daniella”, “Chris”, “Barry”, “Alex”]
/** 2。 使用閉包,閉包型別與引數型別相同 **/
let
b
=
names
。
sorted
(
by
:{(
s1
:
String
,
s2
:
String
)
->
Bool
in
return
s1
>
s2
})
(
“2。 ”
,
b
)
// Prints [“Ewa”, “Daniella”, “Chris”, “Barry”, “Alex”]
/** 3。 使用閉包,可從上下文推斷其引數與返回資料的型別,所以可最佳化為 **/
let
c
=
names
。
sorted
(
by
:{
s1
,
s2
in
return
s1
>
s2
})
(
“3。 ”
,
c
)
// Prints [“Ewa”, “Daniella”, “Chris”, “Barry”, “Alex”]
/** 4。 使用閉包,因閉包只含單條語句,則可省掉“return”,所以可最佳化為 **/
let
d
=
names
。
sorted
(
by
:{
s1
,
s2
in
s1
>
s2
})
(
“4。 ”
,
d
)
// Prints [“Ewa”, “Daniella”, “Chris”, “Barry”, “Alex”]
/** 5。 使用閉包,Swift自動為閉包提供$0,$1,$2之類,表示傳入的引數,所以可以最佳化為 **/
let
e
=
names
。
sorted
(
by
:{
$0
>
$1
})
(
“5。 ”
,
e
)
// Prints [“Ewa”, “Daniella”, “Chris”, “Barry”, “Alex”]
/** 6。 使用閉包,用這種更短的方式,是基於大於號在木Swift中的定義, **/
/** 它的定義與sorted(by:)的引數型別相同,即比較兩個字串並返回布林值 **/
let
f
=
names
。
sorted
(
by
:
>
)
(
“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
)
(
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
{
(
100
)
}
// No output
/** 立即輸出 **/
calledClosure
{
(
200
)
}
// Prints 200
下一篇,Swift 的進階。
讓我們在這裡,遇見明天的自己!姜友華