Go9

golang arry as function parameters

This project is maintained by wangfakang

golang中的指针需要注意点:

1.gonglang中的数组和c中的指针的区别比较大:

在golang中数组名不在是数组的首地址了,如下列子很明显:
func use_array(args [5]int){
    args[1] = 100;
}

func main() {
    var args = [5]int{1, 2, 3, 4, 5};
    use_array(args);
    fmt.Println(args);
}

最终还是输出: 1 2 3 4 5

所以在这里得使用指针:

func use_array(args *[5]int){
    args[1] = 100;
}

func main() {
    var args = [5]int{1, 2, 3, 4, 5};
    use_array(&args);
    fmt.Println(args);
}

这样才可以的,这点在和c语言比起来差别还是蛮大的.

2.还有个小的区别就是在结构体指针中:

type Point struct{
    x int;
    y int;
}

func main() {
    var p *Point;
    p = new(Point);
    p.x = 1;
    p.y = 2;

    fmt.Printf("%p\n", p); // 地址

    fmt.Printf("%p\n", &(p.x));
}

其实和c语言的区别就是在访问结构体指针成员变量的时候不使用->了.

3.golang中函数调用参数全部是传值的,包括 slice/map/chan 在内所有类型,而非传引用:

func main() {
        a := []int{1, 2, 3}
        fmt.Println(a)
        modifySlice(a)
        fmt.Println(a)
}
func modifySlice(data []int) {

        data = nil
}

[1,2,3] [1,2,3]

func main() {
        var arrgs = [5]int{1, 2, 3, 4, 5}; 

        a := []int{1, 2, 3}
        fmt.Printf("arry   %p\n", arrgs)
        fmt.Printf("arry   %p\n", &arrgs)
        fmt.Printf("arry %p\n", &arrgs[0])
        fmt.Printf("%p\n", a)
        fmt.Printf("%p\n", &a) 
        fmt.Printf("%p\n", &a[0])
        fmt.Println(a)
        modifySliceData(a)
        fmt.Println(a)
}

func modifySliceData(data []int) {
        data[0] = 0 
}
arry   %!p([5]int=[1 2 3 4 5])
arry   0xc20803a180
arry 0xc20803a180
0xc20801e040
0xc20801e020
0xc20801e040
[1 2 3]
[0 2 3]

注意slice和数组的区别,以及data = nil 和 data[0] = 0的不同效果.

4.闭包是传递引用的:

package main

import "fmt"

func main() {
        for i := 0; i < 5; i++ {
                defer fmt.Printf("%d ", i) // Output: 4 3 2 1 0
        }
        fmt.Printf("\n")
        for i := 0; i < 5; i++ {
                defer func() { fmt.Printf("%d ", i) }() // Output: 5 5 5 5 5
        }
}

5 5 5 5 5 4 3 2 1 0

注意下面效果:

package main

import "fmt"

func main() {
        for i := 0; i < 5; i++ {
                defer fmt.Printf("%d ", i) // Output: 4 3 2 1 0
        }
        fmt.Printf("\n")
        for i := 0; i < 5; i++ {
                defer func(i int) { fmt.Printf("%d ", i) }(i) // Output: 5 5 5 5 5
        }
}

4 3 2 1 0 4 3 2 1 0

package main

import "fmt"

func main() {
        for i := 0; i < 5; i++ {
                defer fmt.Printf("%d ", i) // Output: 4 3 2 1 0
        }
        fmt.Printf("\n")
        for i := 0; i < 5; i++ {
                i := i
                defer func() { fmt.Printf("%d ", i) }() // Output: 5 5 5 5 5
        }
}

4 3 2 1 0 4 3 2 1 0

即使用了临时变量改变了传引用. 

Communite

在使用中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流

Thx

Author