首页 > 解决方案 > 在 Go 中,即使 []byte 是按值传递给方法的,但还是会修改原始值?

问题描述

通常,只有当它作为指向方法的指针传递时,原始值才会改变。但是我看到这种情况是原始值在作为值传递给方法时发生了变化。这在 Reader 接口的实现中经常发生。

例如:

package main

import (
    "fmt"
    "io"
    "strings"
)

func main() {
    r := strings.NewReader("Hello, Reader!")

    b := make([]byte, 8)
    for {
        n, err := r.Read(b)
        fmt.Printf("n = %v err = %v b = %v\n", n, err, b)
        fmt.Printf("b[:n] = %q\n", b[:n])
        if err == io.EOF {
            break
        }
    }
}

使用 value将变量b传递给 Read 方法

n, err := r.Read(b)

但不知何故,原始值被更改并填充了要打印的数据。

如果我研究 Read 方法的实现

func (r *Reader) Read(b []byte) (n int, err error) {
    if r.i >= int64(len(r.s)) {
        return 0, io.EOF
    }
    r.prevRune = -1
    n = copy(b, r.s[r.i:])
    r.i += int64(n)
    return
}

我们可以清楚地看到它是一个值参数吗?这遵循在 go 中如何通过值传递和复制所有内容。

据我了解,b至少应该作为指针传递

func (r *Reader) Read(b *[]byte) (n int, err error) {

为什么是这样?请帮忙谢谢。

标签: go

解决方案


切片不直接保存其内容。相反,切片包含一个指向其底层数组的指针,该数组包含切片的内容。

所以,基本上是的,你是按值传递的,但值是一个指针“支持数组”。

见:https ://dave.cheney.net/2018/07/12/slices-from-the-ground-up


推荐阅读