Playground - function

來看看 Swift 各種 function 的寫法吧!

Swift 使用 func 當作宣告的保留字

GOLANG 的 fu…. XD

寫 Swift 的 function 會很開心

基本的

func say() {
	println("Hello!")
}

有一個回傳值的

func say() -> String {
	return "Hello!"
}

有多個回傳值的!!! (就是回傳 Tuple)

func say() -> (String, Int) {
	let greeting = "hello"
	let times = 5
	return (greeting, times)
}

say()

有參數的

func say(g: String) {
	println(g)
}

say("Hello")

多個參數

func say(g: String, times: Int) {
	for index in 1...times {
		println(g)
	}
}

say("Hello", 3)

有參數的進階版

func say(greetings g: String) {
	println(g)
}

say("Hello", 3)

此時如果同樣使用 say("hello") 會出錯

因為我們剛剛宣告了外部參數名稱

因此需要:

say(greetings: "hello")

這種寫法在必須代入許多參數時,非常好用,會讓程式可讀性變高

另外,方便起見,也可以加上 #,表示外部參數名稱與 func 內部名稱是一樣的

func say(greetings g: String, #times: Int) {
    for index in 1...times {
        println(g)
    }
}
say(greetings: "Hello", times: 3)

可以看到第一種寫法和第二種寫法是一樣的功用~

給參數預設值

func say(greetings g: String = "hello") {
	println(g)
}

say()

如果呼叫 say() 而沒有給定參數時,會直接使用預設值

常數參數與變數參數

簡單看一下以下的程式碼

func say(greetings: String = "hello") {
    greetings = "\(greetings), welcome!"
    println(greetings)
}

let greetings = "Hello!"
say(greetings: greetings)

我們定義了一個常數,代入 say() 裡面,

但是 say function 裡面必須改變代入的值,於是這個時候 Xcode 就會該了

那要怎麼辦呢?

修改成:

func say(var greetings: String = "hello") {
    greetings = "\(greetings), welcome!"
    println(greetings)
}

let greetings = "Hello!"
say(greetings: greetings)

多加一個 var 宣告,就會 copy 一份傳入,就可以更改值了!

一樣是非常有用的語法!

輸入輸出函數

直接看例子

func swapInt(inout a: Int, inout b: Int) {
    let tmpA = a
    a = b
    b = tmpA
}

var a = 1
var b = 2

swap(&a, &b)

println(a)
println(b)

酷吧

function types 函式型別

直接看例子

func addTwoInt(a: Int, b: Int) -> Int {
    return a + b
}

func mTwoInt(a: Int, b: Int) -> Int {
    return a * b
}

func printHello() {
    println("Hello World")
}

var mathFunction: (Int, Int) -> Int = addTwoInt

println("result: \(mathFunction(2, 3))")

前面宣告了三個 function ,

var mathFunction: (Int, Int) -> Int = addTwoInt

後面的這句的意思是:

我們定義了一個變數叫做 mathFunction

他的型別是「一個 (Int, Int) 的參數,並且回傳 Int」的 function,

簡單說就是 mathFunction 的型別是一個 Function

並指向 addTwoInt 這個 function

所以上面的例子中,mathFunction 代入的 (2, 3) 會丟給 addTwoInt,

並且最後回傳 Int

有 javascript 的味道:

var test = function(a, b) {
  return a + b;
};

var add = test;

console.log("result = " + add(2, 3));

function as parameter types

函式也可以拿來當做參數傳入函式中,

接續上面的例子,加入:

func printResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int )  {
    println("Result: \(mathFunction(a, b))")
}
printResult(mathFunction, 2, 3)

function as return type

函式也可以拿來當做回傳值

就是在原本的回傳符號 -> 後面代入函式型別

這邊直接借別人的例子來參考吧

// 定義兩個 function 
func stepForward(input: Int) -> Int {
    return input + 1
}
func stepBackward(input: Int) -> Int {
    return input - 1
}

// 再定義一個 function ,透過布林值導往上面不同的 function
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    return backwards ? stepBackward : stepForward
}

var currentValue = 3

// 將 chooseStepFunction 指給 moveNearerToZero
// 所以 moveNearerToZero 現在是一個 function 了!
let moveNearerToZero = chooseStepFunction(currentValue > 0)

println("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
    println("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
println("zero!")

Nested Function

就是 funciton 中的 function,變數有分 global、local 變數,function 也有

以上面的例子來改寫:

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
}