Swift----函数 、 闭包 、 枚举 、 类和结构体 、 属性
1 數組排序
1.1 問題
本案例實現一個整型數組排序的函數,數組排序的規則由傳遞的規則函數決定。
1.2 方案
首先定義一個整型數組排序函數sortInts,該函數有一個整型數組類型的參數,該參數必須是輸入輸出參數inout,否則并不能修改數組的值。另外還有一個(Int,Int)->Bool函數類型的參數rule,該參數用于提供數組的排序規則。
然后實現函數sortInts,這里采用數組的冒泡排序算法來實現排序。
接下來實現一個數組排序的規則函數rule1,該函數是(Int,Int)->Bool類型,可以將該函數設置為sortInts函數rule1規則的默認值。
最后將一個整型數組a,傳遞給函數調用,就能實現數組a的排序。當然也可以自定義規則傳遞給函數sortInts。
1.3 步驟
實現此案例需要按照如下步驟進行。
步驟一:定義整型數組排序函數sortInts
首先定義一個整型數組排序函數sortInts,該函數有一個整型數組類型的參數,該參數必須是輸入輸出參數inout,否則并不能修改數組的值。另外還有一個(Int,Int)->Bool函數類型的參數rule,該參數用于提供數組的排序規則,代碼如下所示:
- funcsortInts(inout data:[Int],rule:(Int,Int)->Bool)?{
- }
然后實現函數sortInts,這里采用數組的冒泡排序算法來實現排序,代碼如下所示:
- funcsortInts(inout data:[Int],rule:(Int,Int)->Bool)?{
- forvari=0;i?< data.count-1;i++?{
- forvar j=0;j<data.count-i-1;j++?{
- if?rule(data[j], data[j+1])?{
- swap(&data[j],?&data[j+1])
- }
- }
- }
- }
步驟二:實現規則函數
sortInts函數的rule參數是一個函數類型,需要調用時進行傳遞,該參數用于決定數組的排序規則,可以進行自定義,也就是由程序員來根據程序需求自定義排序規則。
接下來實現一個數組排序的規則函數rule1,該函數是(Int,Int)->Bool類型,可以將該函數設置為sortInts函數rule1規則的默認值,代碼如下所示:
- func?rule1(a:Int,b:Int)->Bool?{
- return a?> b
- }
- //函數類型作為參數傳遞
- funcsortInts(inout data:[Int],rule:(Int,Int)->Bool?= rule1)?{
- forvari=0;i?< data.count-1;i++?{
- forvar j=0;j<data.count-i-1;j++?{
- if?rule(data[j], data[j+1])?{
- swap(&data[j],?&data[j+1])
- }
- }
- }
- }
最后將一個整型數組a,傳遞給函數調用,使用默認規則實現數組a的排序,代碼如下所示:
- var a?=?[1,3,2,4,9,8,5,0,6,7]
- sortInts(&a)
運行結果如圖-1所示:
圖-1
當然也可以自定義規則傳遞給函數sortInts,代碼如下所示:
- //自定義排序規則
- func?rule2(a:Int,b:Int)->Bool?{
- return a<b
- }
- sortInts(&a, rule: rule2)
- func?rule3(a:Int, b:Int)->Bool?{return a%3?> b%3}
- sortInts(&a, rule: rule3)
運行結果如圖-2所示:
圖-2
1.4 完整代碼
本案例中,完整代碼如下所示:
- importUIKit
- func?rule1(a:Int,b:Int)->Bool?{
- return a?> b
- }
- //函數類型作為參數傳遞
- funcsortInts(inout data:[Int],rule:(Int,Int)->Bool?= rule1)?{
- forvari=0;i?< data.count-1;i++?{
- forvar j=0;j<data.count-i-1;j++?{
- if?rule(data[j], data[j+1])?{
- swap(&data[j],?&data[j+1])
- }
- }
- }
- }
- var a?=?[1,3,2,4,9,8,5,0,6,7]
- sortInts(&a)
- a
- //自定義排序規則
- func?rule2(a:Int,b:Int)->Bool?{
- return a<b
- }
- sortInts(&a, rule: rule2)
- func?rule3(a:Int, b:Int)->Bool?{return a%3?> b%3}
- sortInts(&a, rule: rule3)
?
2 將Int數組轉換為對應的String類型的數組
2.1 問題
如果需要將一個很長的閉包表達式作為最后一個參數傳遞給函數,可以使用尾隨閉包來增強函數的可讀性。本案例在Array的map方法中使用尾隨閉包將一個Int類型的數組[16, 58, 510]轉換為對應的String類型的數組["一六", "五八", "五一零"]。
2.2 方案
Array類型有一個map方法,唯一參數是一個閉包表達式,數組中的每一個元素調用用一次該閉包函數,并返回該元素所映射的值,具體的映射方式由閉包表達式決定。
當提供給數組閉包函數后,map方法將返回一個新的數組,數組中包含了與原數組一一對應的映射后的值。
2.3 步驟
實現此案例需要按照如下步驟進行。
步驟一:創建字典digiNames
創建一個數字和中文名映射的字典digiNames,代碼如下所示:
- letdigitNames?=?[
- 0:?"零",?1:?"一",?2:?"二",?3:?"三",?4:?"四",5:?"五",?6:?"六",?7:?"七",?8:?"八",?9:?"九"]
- let numbers?=?[16,?58,?510]
步驟二:調用map方法
numbers數組調用map方法,該方法需要傳遞一個閉包表達式用于規定映射規則,這里采用尾隨閉包的形式,代碼如下所示:
- numbers.map?{(var number)?->?String?in
- var output?=?""
- while number?>?0?{
- //字典下標返回一個可選值
- output?= digitNames[number?%?10]!?+ output
- number?/=?10
- }
- return output
- }
map函數是數組的方法,可以迭代數組中每一元素傳入閉包執行一次,并將執行后的結果做成一個數組返回回來,運行結果如圖-3所示:
圖-3
2.4 完整代碼
本案例中,完整代碼如下所示:
- importUIKit
- letdigitNames?=?[
- 0:?"零",?1:?"一",?2:?"二",?3:?"三",?4:?"四",5:?"五",?6:?"六",?7:?"七",?8:?"八",?9:?"九"]
- let numbers?=?[16,?58,?510]
- //map函數是數組的方法,可以迭代數組中每一元素傳入閉包執行一次,并將執行后的結果做成一個數組返回回來
- let strings?= numbers.map?{(var number)->String?in
- var output?=?""
- while number?>?0?{
- output?= digitNames[number%10]!+output
- number/=10
- }
- return output
- }
- strings
?
3 定義商品條形碼的枚舉
3.1 問題
假設一個倉庫跟蹤系統需要利用兩種不同類型的條形碼來跟蹤商品,有些商品上標有UPC-A格式的一維碼,它是由三個整型數字組成。另外其他一些商品上標有QR格式的二維碼,它是一個字符串,如圖-4、圖-5所示:
圖-4
圖-5
本案例要求使用枚舉來表示商品條碼并設置其關聯值。
3.2 方案
首先把UPC-A碼作為三個整型值的元組,把QR碼作為一個任字符串存儲起來,那么定義一個枚舉Barcode并設置器關聯值。
3.3 步驟
實現此案例需要按照如下步驟進行。
步驟一:定義枚舉Barcode
定義一個枚舉Barcode表示商品條形碼,它有兩個成員UPCA和QRCode,UPCA的關聯值是一個包含三個整型值的元組類型,QRCode的關聯值是一個String類型,代碼如下所示:
- enum Barcode{
- case?UPCA(Int, Int, Int)
- caseQRCode(String)
- }
枚舉的定義不提供任何Int或String的實際值,只是定義而已。
步驟二:使用關聯值
使用剛才定義的枚舉類型Barcode創建一個新的變量productBarcode,并且賦給它兩個成員的關聯值,代碼如下所示:
- varproductBarCode?: Barcode?= Barcode.UPCA(692,?530372375,?0)
- productBarCode?= Barcode.QRCode("ABCDEFSFD")
不同的條形碼可以使用一個switch語句來檢查,代碼如下所示:
- switchproductBarCode?{
- case?.UPCA(let(num, id, check)):
- println("這是條形碼\(num)-\(id)-\(check)")
- case?.QRCode(let pCode):
- println("這是二維碼\(pCode)")
- }
然后調用函數,運行結果如圖-6所示:
圖-6
3.4 完整代碼
本案例中,完整代碼如下所示:
- importUIKit
- //關聯值
- enum Barcode{
- case?UPCA(Int, Int, Int)
- caseQRCode(String)
- }
- varproductBarCode?: Barcode?= Barcode.UPCA(692,?530372375,?0)
- productBarCode?= Barcode.QRCode("ABCDEFSFD")
- switchproductBarCode?{
- case?.UPCA(let(num, id, check)):
- println("這是條形碼\(num)-\(id)-\(check)")
- case?.QRCode(let pCode):
- println("這是二維碼\(pCode)")
- }
?
4 定義幾何形狀的結構體
4.1 問題
屬性分為存儲屬性和計算屬性,存儲屬性就是用常量或變量保存的屬性值。計算屬性的值是通過計算得出的。
按如下要求完成本案例:
1)定義一個Point結構體,用于表示點坐標(x,y);
2)定義一個Size結構體,用于表示形狀的長和寬(width,height);
3)定義一個Rect結構體,用于表示有原點和尺寸的矩形,還提供一個表示中心點center的計算屬性;
4)創建一個Rect類型的實例square,并設置和修改center屬性移動矩形,如圖-7所示:
圖-7
4.2 方案
首先定義Point結構體和Size結構體,Point結構有兩個存儲屬性x和y,用于表示點坐標。Size結構體也有兩個存儲屬性width和height,用于表示長寬。
然后定義矩形Rect結構體,該結構體有兩個存儲屬性一個是Point類型的origin,用于表示原點坐標,另一個是Size類型的size,用于表示矩形的長寬。
Rect結構體還有一個Point類型的計算屬性center,用于表示矩形的中心點,需要提供getter和setter方法獲取和設置其值。
最后創建一個Rect實例square,設置和修改center屬性,查看輸出結果。
4.3 步驟
實現此案例需要按照如下步驟進行。
步驟一:定義Point和Size結構體
首先定義Point結構體和Size結構體,Point結構有兩個存儲屬性x和y,用于表示點坐標。Size結構體也有兩個存儲屬性width和height,用于表示長寬,代碼如下所示:
- struct Point?{
- //存儲屬性
- var x?=?0.0
- var y?=?0.0
- }
- struct Size?{
- ?????//存儲屬性
- var width?=?0.0
- var height?=?0.0
- }
步驟二:定義Rect結構體
然后定義矩形Rect結構體,該結構體有兩個存儲屬性一個是Point類型的origin,用于表示原點坐標,另一個是Size類型的size,用于表示矩形的長寬,代碼如下所示:
- structRect?{
- //存儲屬性
- var origin?=?Point()
- var size?=?Size()
- }
Rect結構體還有一個Point類型的計算屬性center,用于表示矩形的中心點,需要提供getter和setter方法獲取和設置其值,代碼如下所示:
- structRect?{
- //存儲屬性
- var origin?=?Point()
- var size?=?Size()
- //計算屬性
- varcenter:Point?{
- get?{
- letcenterX?= origin.x?+ size.width/2
- letcenterY?= origin.y?+ size.height/2
- return?Point(x: centerX, y: centerY)
- }
- set(newCenter)?{
- origin.x?= newCenter.x?- size.width/2
- origin.y?= newCenter.y?- size.height/2
- }
- }
- }
步驟三:創建square實例
創建一個Rect實例square,原點坐標設置為(0.0,0.0),長寬設置為(10.0,10.0),可以通過點運算調用getter方法獲取到center屬性的值,代碼如下所示:
- var square?=?Rect(origin:?Point(x:?0.0, y:?0.0), size:?Size(width:?10.0, height:?10.0))
- letcenterSquare?= square.center
可以看到center的值為(5.0,5.0),運行結果如圖-8所示:
圖-8
然后重新設置center的值(15,15),設置屬性center的值會調用setter來修改該屬性origin的值,代碼如下所示:
- square.center?=?Point(x:?15, y:?15)
可以看到此時square的origin屬性的值為(10,10),運行結果如圖-9所示:
圖-9
4.4 完整代碼
本案例中,完整代碼如下所示:
- importUIKit
- struct Point?{
- //存儲屬性
- var x?=?0.0
- var y?=?0.0
- }
- struct Size?{
- //存儲屬性
- var width?=?0.0
- var height?=?0.0
- }
- structRect?{
- //存儲屬性
- var origin?=?Point()
- var size?=?Size()
- //計算屬性
- varcenter:Point?{
- get?{
- letcenterX?= origin.x?+ size.width/2
- letcenterY?= origin.y?+ size.height/2
- return?Point(x: centerX, y: centerY)
- }
- set(newCenter)?{
- origin.x?= newCenter.x?- size.width/2
- origin.y?= newCenter.y?- size.height/2
- }
- }
- }
- var square?=?Rect(origin:?Point(x:?0.0, y:?0.0), size:?Size(width:?10.0, height:?10.0))
- letcenterSquare?= square.center
- square.center?=?Point(x:?15, y:?15)
轉載于:https://www.cnblogs.com/hytx/p/5053776.html
總結
以上是生活随笔為你收集整理的Swift----函数 、 闭包 、 枚举 、 类和结构体 、 属性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (区间dp 或 记忆化搜素 )Brack
- 下一篇: 大家看看值多少?