你說上一篇怎麼還沒介紹完就沒了?當然不是阿!且聽我娓娓道來~~~
前面我們介紹完了一些命令式跟結構化程式設計的元素,現在我們要來介紹一個好玩的東西,稱為函式 (function)。
在先前我們已經用過很多函式了喔!像是println()
就是幫我們把東西印出來的函式。
函式的概念就如同數學的函數一樣,你需要給他一個input,然後他會幫你做一些事情,再給出一個output。
我們來實作一個最簡單的函式吧!
function add(a, b)
c = a + b
return c
end
以上是一個可以把兩個數字相加的函式,其中add
是函式的名字,a
跟b
分別是讓使用者輸入的兩個參數,你會住要到函式的裏面有個return c
,return
代表的就是將函式計算完的值輸出,c
就是這個函式將會輸出的值。c = a + b
這個表達式當中包含了一些訊息,他會先將a
跟b
兩個相加之後,並且指定給c
。如此一來我們就完成了將兩個數字相加的函式囉~~~
當函式執行到return
的時候他就會回傳值,並且結束,他並不會執行在return
之後的東西了喔。
Julia傳遞參數的機制是pass-by-sharing,個人認為跟call by reference沒有什麼兩樣就是了。
也就是他會在函式的內部製造一個相對應的變數,並且將變數指向外面丟給函式的值。
所以當你在執行函式的過程中去更動到參數值的話,外面的值也會跟著變喔~~~~
等到大家會寫程式之後就會開始寫出一大堆條件判斷跟迴圈的結構,到時候程式碼就會變得超級長又有很多巢狀。
大家就會進一步發現有些程式碼非常相似,甚至只是改變一下參數就好。這時候怎麼辦呢?
當然是把我們的函式拿來用阿!函式是消除重複的好工具!
像我們之前有寫了非常多的條件判斷,其實重複性很高,感覺很蠢,我們可以這樣做,我們先設法把出拳的判斷獨立出來。
function shape(x)
if x == paper
return "布"
elseif x == scissor
return "剪刀"
elseif x == stone
return "石頭"
end
end
這時候我們就可以把兩方出的拳拿去餵shape()
函式,就可以得到出的拳是甚麼了,然後我們仍舊沒辦法簡化其他部分。
突然神說了一句話,解救了凡人的我。XD
是的,或許你需要一個表來讓你查。
| 布 剪刀 石頭
-------------------
布| 0 -1 1
剪刀| 1 0 -1
石頭| -1 1 0
這時候就要介紹一下Array
這好用的東西啦~~~
這東西就叫陣列。他可以裝下很多的值,並且可以用順序去索引他,像是
A = [2, 3, 5]
A[2]
以上代表著我宣告了A
有三個元素,分別是2、3跟5,接著第二行我做的是取出其中的第二個元素,所以我會得到3
。
可是這是一維的陣列,有沒有二維的阿?
A = [0, -1, 1;
1, 0, -1;
-1, 1, 0]
A[1, 2]
有的!就像上面那樣,我就直接把上面的猜拳對映表直接寫成程式碼了,到時候就像第二行那樣依據不同位置問陣列的值就行了,要注意我們設定的是0~2的值,而這邊陣列起始值是1,所以在使用的時候請記得+1。
簡化完就會變成這樣了。
win = A[x+1, y+1]
x = shape(x)
y = shape(y)
if win == 0
println("平手")
else
println("你出" * x) # 其中*是把兩個字串串接在一起的意思
println("電腦出" * y)
if win == 1
println("你贏了")
else
println("電腦贏了")
end
end
這樣程式碼是不是簡單不少呢?
在Julia,函式支援很多不同的功能,大家繼續看下去就知道了。
一般來說,函式的回傳值只有一個,但是Julia可以回傳多個值喔
funciton foo(a, b, c)
return (a, b, c)
end
只要像上面一樣把他用小括號括起來,並且用逗號隔開就可以一口氣回傳多個值囉~~
如果要傳入的參數數量不一定,那就可以用這個
function foobar(a, b, x::Vararg{Int64})
println(a)
println(b)
println(x)
end
foobar(1, 2, 3, 4)
如果我寫了一個像上面這樣的程式,他會輸出甚麼呢?
1
2
(3, 4)
最後的3
跟4
會把打包在一起輸出喔!
如果你有需要函式提供一些預設值給你的話那就可以用可選參數來幫你。
function foo(a, b, c=10)
...
end
其中我們看到a
跟b
都沒有預設值,c
的預設值是10
,所以當你使用的時候沒有指定c
的值,沒關係,它會自動幫你補上。
foo(1, 2)
但是如果你想用別的值,只要指定c
的值就可以了喔。
foo(1, 2, 3)
這個跟上面的可選參數很像。他大概長這樣
function bar(a, b; i=5, j=6)
...
end
在提供預設值的方面非常像,只插在使用的時候必須指定參數的名字
bar(1, 2, i=10)
在以上這個例子當中,必須要明確地指出i
的值是多少,當你沒有指定j
的值的話,他就會使用預設值。
這兩個功能其實非常相似,我要怎麼取捨呢?
我自己的建議是關鍵字參數建議使用在使用情境彼此互斥的時候,可選參數建議使用在類似情境而可具備預設值的時候。