函数定义

func funcName(param ......) (return type) {
    code......
}
  • param即向函数传入的参数,return type则是函数返回值的类型
  • 自定义求和函数并调用:
package main

import "fmt"

func main() {
    a := 2
    b := 3
    fmt.Println(sum(a, b))
}

func sum(num1, num2 int) int {
    return num1 + num2
}
ending:
5
  • go语言可以有多个返回值:
package main

import "fmt"

func main() {
    c1, c2 := exchange(12, 13)
    fmt.Println(c1, c2)
}

func exchange(a, b int) (int, int) {
    return b, a
}
result:
13 12

函数类型的定义

  • 可以通过type关键字定义一个函数类型
type f1 func(int, int) int
  • 代码解释:定义了一个f1的函数类型,接收两个int类型参数,返回int类型参数
  • 举个栗子:
package main

import "fmt"

type f1 func(int, int) int

func sum(a int, b int) int {
    return a + b
}

func max(a int, b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}

func main() {
    var f f1
    f = sum
    s1 := f(1, 2)
    fmt.Printf("s1: %v\n", s1)
    f = max
    s2 := f(12, 1)
    fmt.Printf("s2: %v\n", s2)
}

return:
[Running] go run "d:\gowork\src\day1017\test.go"
s1: 3
s2: 12

高阶函数

1.函数作为参数传递

package main

import "fmt"

func f1(name string) {
    fmt.Printf("Hi,%s", name)
}

func f2(name string, f3 func(string)) {
    f3(name)
}

func main() {
    f2("cyl", f1)
}
return:
Hi,cyl
[Done] exited with code=0 in 0.989 seconds

2.函数作为返回值传递

package main

import "fmt"

func f1(x, y int) int {
    return x + y
}

func f2(x, y int) int {
    return x - y
}

func f(s string) func(int, int) int {
    switch s { //s是判断操作符
    case "+":
        return f1
    case "-":
        return f2
    default:
        return nil
    }
}

func main() {
    p := f("+")
    r1 := p(12, 12)
    fmt.Printf("r1: %v\n", r1)
    q := f("-")
    r2 := q(12, 11)
    fmt.Printf("r2: %v\n", r2)
}
return:
r1: 24
r2: 1

[Done] exited with code=0 in 1.146 seconds

匿名函数

  • 其实和Java中的匿名类类似,对也和JavaScript中的箭头函数很像。但是,重点来了:go语言中的函数不能嵌套,但是在函数内部可以定义匿名函数
func (param1, param2,......) (return type)
  • 举个例子:
func main() {
    sum := func(a, b int) int {
        return a + b
    }
    fmt.Printf("sum1: %v\n",sum(11,11))
}
return:
sum1: 22

[Done] exited with code=0 in 1.062 seconds

参数传递

1.传递值

  • go语言在默认情况下采用值传递,即在调用情况下不会影响到实际参数

2.传递引用

  • 在函数调用时,将实际参数的地址传递到函数中,这样函数中对参数的修改将影响到实际参数
  • 欧克,先上代码(可以思考一下):
package main

import "fmt"

func main() {
    a := 11
    b := 12
    exchange(&a, &b)
    fmt.Printf("a:%d\n", a)
    fmt.Printf("b:%d\n", b)
}

func exchange(x *int, y *int) {
    var temp int
    temp = *x
    *x = *y
    *y = temp
}
result:
a:12
b:11
  • 这段代码在干什么?
  • 指针是什么,如果大家学习过C语言的话,就会很熟悉,指针p它是一个变量类型,编译器会为它分配内存地址(就是分配空间);而同时它也是指针类型的变量,即它需要按照代码程序指向另外一个内存地址,它指向的内存地址用p表示,p指向的地址中的内容使用*p表示,比如说:
myNode *p1 //可修改p1所指向的内存数据
myNode *&p1 //可修改p1所指向的地址数据
  • 值传递时传递的是值的拷贝,传递后没有任何关系;引用传递传递的是值的引用,即传递前后都指向同一个引用(同一块内存空间)
  • &p:取指针p的地址;而*p指的是指针