结构体方法中接收者传值能对结构体对象造成影响?

对于一个结构体,它的方法的接收者可以传值也可以传指针,传指针。传指针的时候,方法可以对结构体对象内部的数据进行修改,这是毋庸置疑的。问题是在于传值的时候,为什么有时候也能修改?

type H []int
func (h H) test(){} //传值
func (h *H) test(){} //传指针

下面是示例:

package main

import "fmt"

type Heap []int
type H struct {
    h1 []int
    h2 string
}

func (h Heap) test() {
    h[0], h[1] = h[1], h[0] //这里可以成功交换位置,说明修改成功了
    h = h[:2] //这一步操作失效了
}
func (h H) test1() {
    h.h1[0], h.h1[1] = h.h1[1], h.h1[0] //
    h.h2 = "test"
}

func main() {
    l := Heap{1, 2, 3, 4}
    l1 := H{
        h1: []int{1, 2, 3, 4},
    }
    l.test()
    fmt.Println(l1)
    fmt.Println(l)
}

对应的输出

 go run 1.go
{[1 2 3 4] }
[2 1 3 4]

heap类型其实就是一个切片,交换heap中元素的位置可以,但是不能增加或者删除。我现在比较疑惑的就是为什么可以交换位置??值传递,传进去的应该是原heap的拷贝,那么新的heap做的操作应该不会影响到原heap。

讨论数量: 4

数组本身也是指针

2年前 评论

这个测试法该说没对,第一个切片,方法操作是切片本身,切片的方法都不能操作自己那才是有问题吧

2年前 评论
洛圣都五星好市民 (楼主) 2年前

切片是引用类型

2年前 评论

stackoverflow.com/questions/525655... 这里解释了 Slice are pointers to underlying array. It is described in Golang:

Map and slice values behave like pointers: they are descriptors that contain pointers to the underlying map or slice data. Copying a map or slice value doesn't copy the data it points to. Copying an interface value makes a copy of the thing stored in the interface value. If the interface value holds a struct, copying the interface value makes a copy of the struct. If the interface value holds a pointer, copying the interface value makes a copy of the pointer, but again not the data it points to.

2年前 评论
洛圣都五星好市民 (楼主) 2年前

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