函數是一塊執行特定任務的代碼,是構成代碼執行的邏輯結構。編程
在Go語言中,函數的基本組成是:關鍵字func、函數名、參數列表、返回值列表、函數體和返回語句。bash
Go語言函數聲明語法以下:閉包
func function_name( [parameter list] ) [return_types] {
函數體(具體實現的功能)
}
複製代碼
函數語法解析:函數
實例:ui
func calculateBill(price int, no int) int {
var totalPrice = price * no // 商品總價 = 商品單價 * 數量
return totalPrice // 返回總價
}
/* 上述函數有兩個整型的輸入 price 和 no,返回值 totalPrice 爲 price 和 no 的乘積,也是整數類型。*/
複製代碼
若是有連續若干個參數,它們的類型一致,那麼咱們無須一一羅列,只需在最後一個參數後添加該類型。 例如:spa
func calculateBill(price, no int) int {
var totalPrice = price * no
return totalPrice
}
複製代碼
當建立函數時,你定義了函數須要作什麼,經過調用該函數來執行指定任務。指針
調用函數,向函數傳遞參數,並返回值,例如:code
package main
func calculateBill(price, no int) int {
var totalPrice = price * no
return totalPrice
}
func main() {
var ret int
ret = calculateBill(10, 5)
}
複製代碼
函數使用的參數稱爲函數的形參,形參就像定義在函數體內的局部變量。 調用函數,能夠經過兩種方式來傳遞參數:對象
值傳遞是指在調用函數時將實際參數複製一份傳遞到函數中,這樣在函數中若是對參數進行修改,將不會影響到實際參數。
默認狀況下,Go 語言使用的是值傳遞,即在調用過程當中不會影響到實際參數。
例如:
```
package main
import "fmt"
func main() {
/* 定義局部變量 */
var a int = 100
var b int = 200
fmt.Printf("交換前 a 的值爲 : %d\n", a )
fmt.Printf("交換前 b 的值爲 : %d\n", b )
/* 經過調用函數來交換值 */
swap(a, b)
fmt.Printf("交換後 a 的值 : %d\n", a )
fmt.Printf("交換後 b 的值 : %d\n", b )
}
func swap(x, y int) int {
var temp int
temp = x // 保存 x 的值
x = y // 將 y 值賦給 x
y = temp // 將 temp 值賦給 y
return temp;
}
```
如下代碼執行結果爲:
交換前 a 的值爲 : 100<br />
交換前 b 的值爲 : 200<br />
交換後 a 的值 : 100<br />
交換後 b 的值 : 200
複製代碼
引用傳遞是指在調用函數時將實際參數的地址傳遞到函數中,那麼在函數中對參數所進行的修改,將影響到實際參數。
引用傳遞指針參數傳遞到函數內,例如:
```
package main
import "fmt"
func main() {
/* 定義局部變量 */
var a int = 100
var b int= 200
fmt.Printf("交換前,a 的值 : %d\n", a )
fmt.Printf("交換前,b 的值 : %d\n", b )
/* 調用 swap() 函數
* &a 指向 a 指針,a 變量的地址
* &b 指向 b 指針,b 變量的地址
*/
swap(&a, &b)
fmt.Printf("交換後,a 的值 : %d\n", a )
fmt.Printf("交換後,b 的值 : %d\n", b )
}
func swap(x *int, y *int) {
var temp int
temp = *x // 保存 x 地址上的值
*x = *y // 將 y 值賦給 x
*y = temp // 將 temp 值賦給 y
}
```
以上代碼執行結果爲:
交換前,a 的值 : 100<br />
交換前,b 的值 : 200<br />
交換後,a 的值 : 200<br />
交換後,b 的值 : 100
複製代碼
Go語言支持一個函數能夠有多個返回值,若是一個函數有多個返回值,那麼這些返回值必須用 ( 和 ) 括起來。 例如,定義個以矩形的長和寬爲輸入參數,計算並返回矩形面積和周長的函數 rectProps。get
package main
import (
"fmt"
)
func rectProps(length, width float64)(float64, float64) {
var area = length * width
var perimeter = (length + width) * 2
return area, perimeter
}
func main() {
area, perimeter := rectProps(10.8, 5.6)
fmt.Printf("Area: %f Perimeter: %f", area, perimeter)
}
複製代碼
以上實例執行結果爲:Area: 60.480000 Perimeter: 32.800000
從函數中能夠返回一個命名值。一旦命名了返回值,能夠認爲這些值在函數第一行就被聲明爲變量了。
例如:
func rectProps(length, width float64)(area, perimeter float64) {
area = length * width
perimeter = (length + width) * 2
return // 不須要明確指定返回值,默認返回 area, perimeter 的值
}
複製代碼
注意, 函數中的 return 語句沒有顯式返回任何值。因爲 area 和 perimeter 在函數聲明中指定爲返回值, 所以當遇到 return 語句時, 它們將自動從函數返回。
_ 在 Go 中被用做空白符,能夠用做表示任何類型的任何值。
函數rectProps計算的是面積和周長。假使咱們只須要計算面積,而並不關心周長的計算結果,這時可使用空白符 _ 替換周長。 例如:
package main
import (
"fmt"
)
func rectProps(length, width float64) (float64, float64) {
var area = length * width
var perimeter = (length + width) * 2
return area, perimeter
}
func main() {
area, _ := rectProps(10.8, 5.6) // 返回值周長被丟棄
fmt.Printf("Area %f ", area)
}
複製代碼
在程序 area, _ := rectProps(10.8, 5.6) 的這一行,空白符 _ 用來跳過不要的計算結果。
函數定義後可做爲另一個函數的實參數傳入 例如:
package main
import (
"fmt"
"math"
)
func main(){
// 聲明函數變量
getSquareRoot := func(x float64) float64 {
return math.Sqrt(x)
}
// 使用函數
fmt.Println(getSquareRoot(9))
}
複製代碼
閉包是匿名函數,可在動態編程中使用。
Go 語言支持匿名函數,可做爲閉包。匿名函數是一個"內聯"語句或表達式。匿名函數的優越性在於能夠直接使用函數內的變量,沒必要聲明。 示例:
package main
import "fmt"
func getSequence() func() int {
i:=0
return func() int {
i+=1
return i
}
}
func main(){
/* nextNumber 爲一個函數,函數 i 爲 0 */
nextNumber := getSequence()
/* 調用 nextNumber 函數,i 變量自增 1 並返回 */
fmt.Println(nextNumber())
fmt.Println(nextNumber())
fmt.Println(nextNumber())
/* 建立新的函數 nextNumber1,並查看結果 */
nextNumber1 := getSequence()
fmt.Println(nextNumber1())
fmt.Println(nextNumber1())
}
複製代碼
函數 getSequence() ,返回另一個函數(匿名函數),該函數的目的是在閉包中遞增 i 變量。
方法就是一個包含了接受者的函數,接受者能夠是命名類型或者結構體類型的一個值或者是一個指針。全部給定類型的方法屬於該類型的方法集。 語法格式以下:
func (variable_name variable_data_type) function_name() [return_type]{
/* 函數體*/
}
複製代碼
下面定義一個結構體類型和該類型的一個方法:
package main
import (
"fmt"
)
/* 定義結構體 */
type Circle struct {
radius float64
}
func main() {
var c1 Circle
c1.radius = 10.00
fmt.Println("圓的面積 = ", c1.getArea())
}
//該 method 屬於 Circle 類型對象中的方法
func (c Circle) getArea() float64 {
//c.radius 即爲 Circle 類型對象中的屬性
return 3.14 * c.radius * c.radius
}
複製代碼
以上代碼執行結果爲: 的面積 = 314