Go语言函数参数

    /    2018-12-10

函数参数

实际参数简称“实参”。在调用有参函数时,函数名后面括号中的参数称为“实际参数”,实参可以是常量、变量或表达式。

自定义函数中的“形参”全称为"形式参数" 由于它不是实际存在变量,所以又称虚拟变量。实参和形参可以重名。形参的作用域是整个函数体就像定义在函数体内的局部变量。

参数传递

第一种,值传递:指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

package main

import (
    "fmt"
)

func main() {
    var x int = 1
    var y int = 2
    // 值传递
    z := sum(x, y)
    fmt.Println(z)
}

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

第二种,引用传递:是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

package main
import (
    "fmt"
)

func swap(x, y *string) {
    var temp string

    temp = *x
    *x = *y
    *y = temp

}

func main() {
    var course1, course2 string = "Python", "Golang"

    swap(&course1, &course2)

    fmt.Println(course1, course2)
}

第三种,固定类型可变参数:就是函数的参数不是固定的,后面的类型是固定的。

package main

import (
    "fmt"
)

func variable(name string, course ...string) {
    fmt.Println("可变参数的长度:", len(course))
    for _, val := range course {
        fmt.Println(name, val)
    }
}

func main() {
    variable("oldboy", "linux", "golang", "python", "java")
}

第四种,任意类型的不定参数:就是函数的参数和每个参数的类型都不是固定的。形参用interface{}传递任意类型数据。

package main

import (
    "fmt"
)

type Person struct {
    name string
}

func variable(values ...interface{}) {
    for _, val := range values {
        switch v := val.(type) {
        case int:
            fmt.Println("val type is int ", v)
        case float64:
            fmt.Println("val type is float ", v)
        case string:
            fmt.Println("val type is string ", v)
        case bool:
            fmt.Println("val type is bool ", v)
        case Person:
            fmt.Println("val type is Person ", v.name)
        case *Person:
            fmt.Println("val type is *Person ", v.name)
        default:
            fmt.Println("val type is unknow ", v)
        }
    }
}

func main() {
    temp_int := 1
    temp_float := 5.6
    temp_string := "hello"
    temp_bool := true
    temp_person1 := &Person{name: "jack"}
    temp_person2 := Person{name: "rose"}
    var temp_float32 float32 = 6.6

    variable(temp_int, temp_float, temp_string, temp_bool, temp_person1, temp_person2, temp_float32)
}

第五种,函数类型参数:就是函数类型赋值给变量,作为参数传递应用。

package main

import "fmt"

// 定义函数类型
type myfunc func(string, string)

func addperfix(perfix, name string) {
    fmt.Println(perfix, name)
}

// 第二个参数用匿名函数当参数
func sayhello(name string, f myfunc) {
    f("hello", name)
}

func main() {
    sayhello("oldboy", addperfix)
}

注意:

1)Go语言函数中的参数不支持默认值。

2)无论是值传递,还是引用传递,传递给函数的都是变量的副本,不过,值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址拷贝更为高效。而值拷贝取决于拷贝的对象大小,对象越大,则性能越低。

3)map、slice、chan、指针、interface默认以引用的方式传递。

4)函数的可变参数只能有一个,且必须是最后一个。

5)在参数赋值时可以不用用一个一个的赋值,可以直接传递一个数组或者切片,特别注意的是在参数后加上“…”即可。实例如下:

package main

import (
    "fmt"
)

func oldboy(name string, c ...string) string {
    var course string
    for _, val := range c {
        course += val
    }

    return fmt.Sprintf(name, course)
}

func main() {
    course := []string{"linux ", "golang ", "python ", "java"}
    res := oldboy("oldboy: %s", course...) // ... 展开slice
    fmt.Println(res)
}

(8)

分享至