多個參數
package main
import "fmt"
func add(x, y int) (ret int) {
//x的類型省略,x和相鄰的y同類型,返回值指定爲ret int,如果返回值僅int,則可返回任意的int數據
ret = x + y //ret直接使用,無須再定義
return //可以省略ret,不能省略return
}
func main() {
ret := add(10, 20)
fmt.Println(ret)
}
可變參數
package main
import "fmt"
//有一個整數參數x和一個可變參數nums,編寫函數實現x是否在nums中出現
func hasX(x int, nums ...int) bool {
for _, v := range nums {
if x == v {
return true
}
}
return false
}
func main() {
has := hasX(10, 12, 34, 65, 78)
if has {
fmt.Println("x出現在nums切片中")
} else {
fmt.Println("x沒有出現在nums切片中")
}
}
10會傳參給x,12, 34, 65, 78會以切片形式傳參給nums,在hasX函數體內可以將nums當作切片處理。
多個返回值
package main
import "fmt"
func addSub(x, y int) (int, int) {
add := x + y
sub := x - y
return add, sub
}
func main() {
ret1, ret2 := addSub(20, 10)
fmt.Println(ret1, ret2)
}
addSub函數分別實現對傳入參數相加和相減操作,並且返回兩個結果,使用兩個變量接受返回值。當然也可以對多個返回值指定名稱,也可以如同省略參數類型一樣省略返回值類型。
package main
import "fmt"
func addSub(x, y int) (add, sub int) {
add = x + y
sub = x - y
return
}
func main() {
ret1, ret2 := addSub(20, 10)
fmt.Println(ret1, ret2)
}
定義函數類型
我們可以使用type關鍵字來定義一個函數類型,具體格式如下:
type calculation func(int, int) int
上面語句定義了一個calculation類型,它是一種函數類型,這種函數接收兩個int類型的參數並且返回一個int類型的返回值。
簡單來說,凡是滿足這個條件的函數都是calculation類型的函數,例如下面的add和sub是calculation類型。
func add(x, y int) int {
return x + y
}
func sub(x, y int) int {
return x - y
}
add和sub都能賦值給calculation類型的變量。
var c calculation
c = add
被賦值的c變量,類型是main.calculation類型,c()等同於add()
package main
import "fmt"
type calculation func(int, int) int
func add(x, y int) int {
return x + y
}
func sub(x, y int) int {
return x - y
}
func main() {
var fun1, fun2 calculation
fun1, fun2 = add, sub
ret1 := fun1(20, 10)
ret2 := fun2(20, 10)
fmt.Printf("fun1:%T\tfun2:%T\n", fun1, fun2)
fmt.Println(ret1, ret2)
}
函數作爲參數
package main
import "fmt"
func add(x, y int) int {
return x + y
}
func sum(x, y int, op func(int, int) int) (ret int) {
//sum函數共有x,y,op三個參數,op的類型是op func(int, int) int,sum函數的返回值是ret int
ret = op(x, y)
return
}
func main() {
res := sum(10, 20, add)
fmt.Println(res)
}
當然函數也可以作爲函數的返回值,如下匿名函數部分。
匿名函數
go語言也可以將函數看做是對象,先看看匿名函數作爲函數返回值
package main
import "fmt"
func bag() func() {
return func() {
fmt.Println("hello,world")
}
}
func main() {
fun := bag()
fun()
}
如上,bag函數的返回值是一個匿名函數,定義fun變量接受這個匿名函數之後就可以調用它。
package main
import "fmt"
func bag() {
func() {
fmt.Println("hello,world")
}()
}
func main() {
bag()
}
如上,並不需要bag函數返回匿名函數,bag函數內需要立即調用,可直接在定義匿名函數體後加()
進行立即執行。
當然,也可以寫成如下形式
package main
import "fmt"
func bag() {
fun:=func() {
fmt.Println("hello,world")
}
fun()
}
func main() {
bag()
}
閉包
閉包=函數+引用函數外變量
func adder() func(int) int {
var x int
return func(y int) int {
x += y
return x
}
}
上述adder中的匿名函數就是閉包,該匿名函數使用了其外部變量x。
package main
import "fmt"
func closebag(base int) (func(int) int, func(int) int) {
add := func(x int) int {
base += x
return base
}
sub := func(y int) int {
base -= y
return base
}
return add, sub
}
func main() {
fun1, fun2 := closebag(200)
a := fun2(10)
b := fun1(20)
fmt.Println(a, b)
}
上述closebag函數中的兩個匿名函數分別使用了add、sub兩個變量來接受,並且返回了這兩個函數變量,在這兩個匿名函數中都使用了其函數外部變量base。因此這兩個匿名函數都屬於閉包。
package main
import (
"fmt"
"strings"
)
//檢查字符串name是否值由suff字符結尾,如果不是返回name+suff
func checkSuff(suff string) (func(string)string) {
//checkSuff的返回值是一個有string類型參數和string類型返回值的匿名函數
return func(name string)string{
if !strings.HasSuffix(name,suff){
return name+suff
}
return name
}
}
func main() {
fun:=checkSuff(".doc")
str:=fun("word")
fmt.Println(str)
}