[golang]切片函数传递,在函数中使用append,在调用用输出未见改动,具体见图

切片函数传递,在函数中使用append,在调用用输出未见改动,具体见代码和运行图:

package main

import "fmt"

type student struct {
    id   int
    name string
    age  int
}

func demo(ce []student) {
    ce[1].age = 999
    ce = append(ce, student{4, "xiaowan2g", 98})
    fmt.Printf("%p\n", ce)
    fmt.Println(len(ce), cap(ce))
    fmt.Println(ce)
}
func main() {
    var ce []student
    ce = []student{
        student{1, "xiaoming", 22},
        student{2, "xiaozhang", 33},
    }
    ce = append(ce, student{3, "xiaowang", 56})
    fmt.Printf("%p\n", ce)
    fmt.Println(len(ce), cap(ce))
    demo(ce)
    fmt.Println(len(ce), cap(ce))

    fmt.Println(ce)
}

运行截图:

【golang】切片函数传递,在函数中使用append,在调用用输出未见改动,具体见图

ce 的地址是一样的,预计结果应该都是输出 [{1 xiaoming 22} {2 xiaozhang 999} {3 xiaowang 56} {4 xiaowan2g 98}],未能如愿,不知道问题出在哪里?求教!

最佳答案
  1. golang 里面函数参数只有值传递,没有传引用的。就算函数入参是个指针,那也是对入参指针的copy。
  2. fmt.Printf("%p\n", ce) 打印的是slice内部数组的地址,而不是ce实际的地址。实际的地址得用unsafe.Pointer打印。 你将 fmt.Printf("%p\n", ce) 改为 fmt.Println(unsafe.Pointer(&ce)) 试试,就明白了。
2年前 评论
讨论数量: 4

需要传递引用才行

2年前 评论
package main

import "fmt"

type student struct {
    id   int
    name string
    age  int
}

func demo(ce *[]student) {
    (*ce)[1].age = 999
    ce2 := append(*ce, student{4, "xiaowan2g", 98})
    fmt.Printf("%p\n", ce2)
    fmt.Println(len(ce2), cap(ce2))
    fmt.Println(ce2)
    *ce = ce2
}
func main() {
    var ce []student
    ce = []student{
        student{1, "xiaoming", 22},
        student{2, "xiaozhang", 33},
    }
    ce = append(ce, student{3, "xiaowang", 56})
    fmt.Printf("%p\n", ce)
    fmt.Println(len(ce), cap(ce))
    demo(&ce)
    fmt.Println(len(ce), cap(ce))

    fmt.Println(ce)
}

改成这样可以。这里为什么输出的内存地址一样,但是显示的内容不一样,我怀疑这里显示的是切片底层共享数组的地址。

2年前 评论

@deatil 嗯,知道改成引用可以,也调整过。只是没想明白,不传引用的情况下,内存地址一样的,改变ce[1]的值有效,append一个元素却无效

2年前 评论
  1. golang 里面函数参数只有值传递,没有传引用的。就算函数入参是个指针,那也是对入参指针的copy。
  2. fmt.Printf("%p\n", ce) 打印的是slice内部数组的地址,而不是ce实际的地址。实际的地址得用unsafe.Pointer打印。 你将 fmt.Printf("%p\n", ce) 改为 fmt.Println(unsafe.Pointer(&ce)) 试试,就明白了。
2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!