標籤:
1.0 函數的定義與調用( Defining and Calling Functions )
習慣了C#了文法,看到下面的這樣定義輸入參數實在感到非常彆扭,func 有點 Javascript的感覺,還算習慣。函數調用與其他語言沒什麼區別
//有輸入參數和傳回值的函數//輸入參數為名name,資料類型為String//傳回值 String類型func SayHello(name:String) ->String { return "Hello,"+name;}//調用函數SayHello("_luo")
2.0 函數參數與傳回值 ( Function Parameters and Return Values )
// 2.1 多重輸入參數 ( Multiple Input Parameters )func HalfOpenRangeLength(start:Int,end:Int) ->Int{ return end - start;}// 2.2 無參函數 ( Functions Without Parameters )func SayHelloWorld()->String{return "Hello World";}// 2.3 無傳回值函數 ( Functions Without Return Values )func SayGoodbye(name:String){ println("Goodbye,\(name)");}// 2.4 多重傳回值函數 (Functions with Multiple Return Values )//你可以用元組(tuple)類型讓多個值作為一個複合值從函數中返回。//計算一個字串中母音,輔音和其他字母的個數func Count(str:String)->(vowels:Int,consonants:Int,others:Int){ var vowels=0,consonants=0,others=0; for item in str { switch String(item).lowercaseString{ case "a","e","i","o","u":vowels++; case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":consonants++; default:others++; } } return (vowels,consonants,others);}
3.0 函數參數名稱 ( Function Parameter Names )
上面的函數中的參數名僅在函數體中使用,不能這函數調用時使用,這種類型的參數名稱為[局部參數名]。
與C#相比,Swift 有外部參數名。
外部參數名,是為了在調用函數時,可以指出各個實參的用途是什麼。
(個人覺得實在是太不人性化了,為了知道這個參數的意義還要弄個外部參數名。C#就比較好了 在vs,只要寫了注釋,調用的時候就會顯示各個參數的用途,頓時感覺到vs的強大)
// 3.1 外部參數名 ( External Parameter Names )//外部參數名寫在局部參數名之前,用空格分隔//如果你提供了外部參數名,那麼函數在被調用時,必須使用外部參數名。//----沒有外部參數名的寫法??-----func Join(str1:String,str2:String,joinner:String)->String{ return str1 + joinner + str2;}//當你調用這個函數時,這三個字串的用途是不清楚的Join("Hello", "World", ",")//為了讓這些字串的用途更為明顯,我們為Join函數添加外部參數名func Join(string str1:String,toString str2:String,withJoiner joinner:String)->String{ return str1 + joinner + str2;}//現在,你可以使用這些外部參數名以一種清晰地方式來調用函數了:Join(string: "Hello", toString: "World", withJoiner: ",");// 3.2 簡寫外部參數名 ( Shorthand External Parameter Names )//如果你需要提供的外部參數名就是局部參數名,那麼唯寫一次參數名並用#號作為首碼就可以了func ContainsCharacter(#str:String,#char:Character)->Bool{ for item in str{ if(item == char){ return true; } } return false;}ContainsCharacter(str: "klsdkfjoiwenklaskdf", char: "a")// 3.3 預設參數值 ( Default Parameter Values )// 3.4 預設值參數的外部參數名 ( External Names for Parameters with Default Values )// 在大多情況下,給帶預設值參數起一個外部參數名是很有用的。這樣可以保證當函數被調用時,實參的意圖是明顯的// 為了使定義外部參數名更加堅定,當你未給帶預設值的參數提供外部參數名是,Swift 會自動提供外部名字。此時外部參數名字與局部名字是一樣的,就像你已經在局部參數名前寫了#一樣func Join(str1:String,str2:String,joinner:String=" ")->String{ return str1 + joinner + str2;}Join("Hello", "World", joinner: "-")// 3.5 可變參數 ( Variadic Parameters )//通過這變數類型名後加...的方式來定義可變參數//計算一組任意長度數位算術平均數func AritheticMean(numbers:Double...)->Double{ var total:Double=0; for number in numbers{ total += number; } return total / Double(numbers.count);}AritheticMean(1,2,2,1,23,22,12)//注意:一個函數至多能有一個可變參數,而且它必須是參數表中的最後一個// 3.6 常量參數和變數參數 ( Constant and Variable Parameters )//函數參數預設上常量。試圖這函數體中更改參數值將會導致變異錯誤,可以通過做參數名前加關鍵字var來定義變數參數//使文字靠右對齊func TextAlignRight(var str:String,totallength:Int,pad:Character)->String{ let amountToPad = totallength - count(str); if(amountToPad<=0){ return str; } for _ in 1...amountToPad{ str=String(pad) + str; } return str;}TextAlignRight("loding", 10, "-")---------//"----loding"TextAlignRight("Error", 10, "-")----------//"-----Error"
4.0 函數類型(Function Types)
每個函數都有種特定的函數類型,由函數的參數類型和傳回型別組成。
例如:
func addTwoInts(a: Int, b: Int) -> Int { return a + b}func multiplyTwoInts(a: Int, b: Int) -> Int { return a * b}
這個例子中定義了兩個簡單的數學函數:addTwoInts
和 multiplyTwoInts
。這兩個函數都傳入兩個 Int
類型, 返回一個合適的Int
值。
這兩個函數的類型是 (Int, Int) -> Int
,可以讀作“這個函數類型,它有兩個 Int
型的參數並返回一個Int
型的值。”。
下面是另一個例子,一個沒有參數,也沒有傳回值的函數:
func printHelloWorld() { println("hello, world")}
這個函數的類型是:() -> ()
,或者叫“沒有參數,並返回 Void
類型的函數”。沒有指定傳回型別的函數總返回 Void
。在Swift中,Void
與空的元組是一樣的。
接下來繼續看函數類型的使用,可以發現很類似 C# 的委託了
// 4.1 使用函數類型 (Using Function Types)//在 Swift 中,使用函數類型就像使用其他類型一樣。例如,你可以定義一個類型為函數的常量或變數,並將函數賦值給它:var mathFunction: (Int, Int) -> Int = addTwoIntsprintln("Result: \(mathFunction(2, 3))")// prints "Result: 5"//有相同匹配類型的不同函數可以被賦值給同一個變數,就像非函數類型的變數一樣:mathFunction = multiplyTwoIntsprintln("Result: \(mathFunction(2, 3))")// prints "Result: 6"//就像其他類型一樣,當賦值一個函數給常量或變數時,你可以讓 Swift 來推斷其函數類型:let anotherMathFunction = addTwoInts// anotherMathFunction is inferred to be of type (Int, Int) -> Int// 4.2 函數類型作為參數類型(Function Types as Parameter Types)//你可以用(Int, Int) -> Int這樣的函數類型作為另一個函數的參數類型。這樣你可以將函數的一部分實現交由給函數的調用者。//下面是另一個例子,正如上面的函數一樣,同樣是輸出某種數學運算結果:func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) { println("Result: \(mathFunction(a, b))")}printMathResult(addTwoInts, 3, 5)// prints "Result: 8”// 4.3 函數類型作為傳回型別(Function Type as Return Types)//你可以用函數類型作為另一個函數的傳回型別。你需要做的是在返回箭頭(->)後寫一個完整的函數類型。//下面的這個例子中定義了兩個簡單函數,分別是 stepForward 和stepBackward。stepForward 函數返回一個比輸入值大一的值。stepBackward 函數返回一個比輸入值小一的值。這兩個函數的類型都是 (Int) -> Int:func stepForward(input: Int) -> Int { return input + 1}func stepBackward(input: Int) -> Int { return input - 1}//下面這個叫做 chooseStepFunction 的函數,它的傳回型別是 (Int) -> Int 的函數。chooseStepFunction 根據布爾值 backwards 來返回 stepForward 函數或 stepBackward 函數:func chooseStepFunction(backwards: Bool) -> (Int) -> Int { return backwards ? stepBackward : stepForward}//你現在可以用 chooseStepFunction 來獲得一個函數,不管是那個方向:var currentValue = 3let moveNearerToZero = chooseStepFunction(currentValue > 0)// moveNearerToZero now refers to the stepBackward() function//上面這個例子中計算出從 currentValue 逐漸接近到0是需要向正數走還是向負數走。currentValue 的初始值是3,這意味著 currentValue > 0 是真的(true),這將使得 chooseStepFunction 返回 stepBackward 函數。一個指向返回的函數的引用儲存在了 moveNearerToZero 常量中。//現在,moveNearerToZero 指向了正確的函數,它可以被用來數到0:println("Counting to zero:")// Counting to zero:while currentValue != 0 { println("\(currentValue)... ") currentValue = moveNearerToZero(currentValue)}println("zero!")// 3...// 2...// 1...// zero!
5.0 嵌套函數(Nested Functions)
在上面的例子中,你所見到的所有函數都叫全域函數(global functions),它們定義在全域域中。你也可以把函數定義在別的函數體中,稱作嵌套函數(nested functions)。
預設情況下,嵌套函數是對外界不可見的,但是可以被他們封閉函數(enclosing function)來調用。一個封閉函數也可以返回它的某一個嵌套函數,使得這個函數可以在其他域中被使用。
你可以用返回嵌套函數的方式重寫 chooseStepFunction
函數:
func chooseStepFunction(backwards: Bool) -> (Int) -> Int { func stepForward(input: Int) -> Int { return input + 1 } func stepBackward(input: Int) -> Int { return input - 1 } return backwards ? stepBackward : stepForward}var currentValue = -4let moveNearerToZero = chooseStepFunction(currentValue > 0)// moveNearerToZero now refers to the nested stepForward() functionwhile currentValue != 0 { println("\(currentValue)... ") currentValue = moveNearerToZero(currentValue)}println("zero!")
結果:
// -4...// -3...// -2...// -1...// zero!
Swift - 函數(Functions)總結 - 比較 與 C# 的異同