Golang字节。缓冲区-传递值问题

Golang字节。缓冲区-传递值问题,go,pass-by-value,Go,Pass By Value,下面的golang(go1.10.2)代码将给出意外的输出 package main import ( "bytes" "fmt" ) func main() { var b bytes.Buffer //Commenting the below line will fix the problem b.WriteString("aas-") fmt.Printf("Before Calling - \"%s\"\n", b.String())

下面的golang(go1.10.2)代码将给出意外的输出

package main

import (
    "bytes"
    "fmt"
)

func main() {
    var b bytes.Buffer
    //Commenting the below line will fix the problem
    b.WriteString("aas-")
    fmt.Printf("Before Calling - \"%s\"\n", b.String())
    b = makeMeMad(b)
    fmt.Printf("FinalValue - \"%s\"\n", b.String())
}

func makeMeMad(b bytes.Buffer) bytes.Buffer {
    b.WriteString("xcxxcx asdasdas dasdsd asdasdasdasd")
    fmt.Printf("Write More - \"%s\"\n", b.String())

    /*
        //This will fix the problem
        var newBuffer bytes.Buffer
        newBuffer.WriteString(b.String())
        return newBuffer
    */
    return b
}
输出

Before Calling - "aas-"
Write More - "aas-xcxxcx asdasdas dasdsd asdasdasdasd"
FinalValue - "aas-                                   "
我希望在输出的最后一行中出现“aas xcxxcx asdasdas dasdas asdasdasd”。请任何人解释一下。

第节提到:

如果接口值包含指针*T,则方法调用可以获得 通过取消对指针的引用而创建的值,但如果 如果包含值T,则方法调用无法获得有用的方法 指针

即使在编译器可以将值的地址 传递给该方法,如果该方法修改了值,则更改将 在呼叫者中迷失。例如,如果 字节。缓冲区使用值接收器而不是指针,此代码:

将标准输入复制到buf的副本中,而不是buf本身

错误是因为您没有在
makeMeMad
函数中传递缓冲区地址。这就是为什么它没有重写main函数中的原始缓冲区。 将地址传递给已创建的缓冲区,以将字符串附加到现有缓冲区值

package main

import (
    "bytes"
    "fmt"
)

func main() {
    var b bytes.Buffer
    //Commenting the below line will fix the problem
    b.WriteString("aas-")
    fmt.Printf("Before Calling - \"%s\"\n", b.String())
    makeMeMad(&b)
    fmt.Printf("FinalValue - \"%s\"\n", b.String())
}

func makeMeMad(b *bytes.Buffer) {
    b.WriteString("xcxxcx asdasdas dasdsd asdasdasdasd")
    fmt.Printf("Write More - \"%s\"\n", b.String())

    /*
        //This will fix the problem
        var newBuffer bytes.Buffer
        newBuffer.WriteString(b.String())
        return newBuffer
    */
}
package main

import (
    "bytes"
    "fmt"
)

func main() {
    var b bytes.Buffer
    //Commenting the below line will fix the problem
    b.WriteString("aas-")
    fmt.Printf("Before Calling - \"%s\"\n", b.String())
    ab := makeMeMad(b)
    fmt.Printf("FinalValue - \"%s\"\n", ab.String())
}

func makeMeMad(b bytes.Buffer) bytes.Buffer {
    b.WriteString("xcxxcx asdasdas dasdsd asdasdasdasd")
    fmt.Printf("Write More - \"%s\"\n", b.String())

    /*
        //This will fix the problem
        var newBuffer bytes.Buffer
        newBuffer.WriteString(b.String())
        return newBuffer
    */
    return b
}

或者,您可以将返回的缓冲区值分配给一个新变量,您将获得更新的缓冲区值

package main

import (
    "bytes"
    "fmt"
)

func main() {
    var b bytes.Buffer
    //Commenting the below line will fix the problem
    b.WriteString("aas-")
    fmt.Printf("Before Calling - \"%s\"\n", b.String())
    makeMeMad(&b)
    fmt.Printf("FinalValue - \"%s\"\n", b.String())
}

func makeMeMad(b *bytes.Buffer) {
    b.WriteString("xcxxcx asdasdas dasdsd asdasdasdasd")
    fmt.Printf("Write More - \"%s\"\n", b.String())

    /*
        //This will fix the problem
        var newBuffer bytes.Buffer
        newBuffer.WriteString(b.String())
        return newBuffer
    */
}
package main

import (
    "bytes"
    "fmt"
)

func main() {
    var b bytes.Buffer
    //Commenting the below line will fix the problem
    b.WriteString("aas-")
    fmt.Printf("Before Calling - \"%s\"\n", b.String())
    ab := makeMeMad(b)
    fmt.Printf("FinalValue - \"%s\"\n", ab.String())
}

func makeMeMad(b bytes.Buffer) bytes.Buffer {
    b.WriteString("xcxxcx asdasdas dasdsd asdasdasdasd")
    fmt.Printf("Write More - \"%s\"\n", b.String())

    /*
        //This will fix the problem
        var newBuffer bytes.Buffer
        newBuffer.WriteString(b.String())
        return newBuffer
    */
    return b
}
工作守则

或者,您可以创建一个全局缓冲区,以便在任何函数写入缓冲区时更改缓冲区内的值

package main

import (
    "bytes"
    "fmt"
)

var b bytes.Buffer

func main() {
    //Commenting the below line will fix the problem
    b.WriteString("aas-")
    fmt.Printf("Before Calling - \"%s\"\n", b.String())
    b := makeMeMad(b)
    fmt.Printf("FinalValue - \"%s\"\n", b.String())
}

func makeMeMad(b bytes.Buffer) bytes.Buffer {
    b.WriteString("xcxxcx asdasdas dasdsd asdasdasdasd")
    fmt.Printf("Write More - \"%s\"\n", b.String())

    /*
        //This will fix the problem
        var newBuffer bytes.Buffer
        newBuffer.WriteString(b.String())
        return newBuffer
    */
    return b
}

在引擎盖下
字节。缓冲区
包含其他未报告的字段
引导
数组和
buf
切片。当缓冲区内容很小时,切片指向内部数组以避免分配。当您将
bytes.Buffer
参数作为值传递时,函数将接收一个副本。Slice是引用类型,因此此副本的Slice继续指向原始缓冲区的数组。当您写入此副本的切片时,实际上是写入了original的引导数组,而副本的数组保持不变(“aas-”在我们的例子中)。然后你把这一份还回去,你就可以打印了。但当您将其分配给包含原始数据的变量时,引导数组首先被分配(“aas-”),然后
buf
slice指向它。 引导数组是[64]字节,所以您可以在代码段中使用大于64的长字符串文本,当缓冲区分配buf切片时,事情会按预期进行。
这也是一个简化的例子,试图说明为什么所有这些看起来都很有创意。

但他确实写了
b=…
对吗?因此,该值被重新写入
b
,是吗?@leapbebop check编辑的回答OP正在将缓冲区的副本传递给函数。他返回一个修改过的缓冲区副本,该副本被重新分配给原始变量。@leapbebop是,该值更新了缓冲区的状态,但返回时丢弃了缓冲区changes@leafbebop如果你仔细检查,就没有什么新的了,你仍然是未写入主缓冲区。如果您真的想在缓冲区中添加一些内容,请使用此选项。此问题已在Go的github上发布为一个问题,您可以在此处查看:因此,您体验的答案如下:<代码>字节。缓冲区决不能按原样传递,始终传递指向它的指针。