dongli8979 2018-07-19 09:32
浏览 277

Golang bytes.Buffer-传递值问题

The below golang(go1.10.2) code will give an unexpected output

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\"
", b.String())
    b = makeMeMad(b)
    fmt.Printf("FinalValue - \"%s\"
", b.String())
}

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

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

Output

Before Calling - "aas-"
Write More - "aas-xcxxcx asdasdas dasdsd asdasdasdasd"
FinalValue - "aas-                                   "

I was expecting "aas-xcxxcx asdasdas dasdsd asdasdasdasd" in the last line of output. Could anyone please explain.

  • 写回答

2条回答 默认 最新

  • doukun0888 2018-07-19 09:49
    关注

    It is mentioned in Golang FAQ section as:

    If an interface value contains a pointer *T, a method call can obtain a value by dereferencing the pointer, but if an interface value contains a value T, there is no useful way for a method call to obtain a pointer.

    Even in cases where the compiler could take the address of a value to pass to the method, if the method modifies the value the changes will be lost in the caller. As an example, if the Write method of bytes.Buffer used a value receiver rather than a pointer, this code:

    var buf bytes.Buffer
    io.Copy(buf, os.Stdin)
    

    would copy standard input into a copy of buf, not into buf itself

    The error is because you're not passing the address of buffer inside makeMeMad function. That's why it has not override the original buffer inside main function. Pass address to the created buffer to append string to the existing buffer value.

    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\"
    ", b.String())
        makeMeMad(&b)
        fmt.Printf("FinalValue - \"%s\"
    ", b.String())
    }
    
    func makeMeMad(b *bytes.Buffer) {
        b.WriteString("xcxxcx asdasdas dasdsd asdasdasdasd")
        fmt.Printf("Write More - \"%s\"
    ", b.String())
    
        /*
            //This will fix the problem
            var newBuffer bytes.Buffer
            newBuffer.WriteString(b.String())
            return newBuffer
        */
    }
    

    Playground Example

    Or you can assign the returned buffer value to a new variable and you will get the updated buffer value.

    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\"
    ", b.String())
        ab := makeMeMad(b)
        fmt.Printf("FinalValue - \"%s\"
    ", ab.String())
    }
    
    func makeMeMad(b bytes.Buffer) bytes.Buffer {
        b.WriteString("xcxxcx asdasdas dasdsd asdasdasdasd")
        fmt.Printf("Write More - \"%s\"
    ", b.String())
    
        /*
            //This will fix the problem
            var newBuffer bytes.Buffer
            newBuffer.WriteString(b.String())
            return newBuffer
        */
        return b
    }
    

    Working Code on Go Playground

    Or you can create a global buffer to change the value inside the buffer whenever it is written by any function.

    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\"
    ", b.String())
        b := makeMeMad(b)
        fmt.Printf("FinalValue - \"%s\"
    ", b.String())
    }
    
    func makeMeMad(b bytes.Buffer) bytes.Buffer {
        b.WriteString("xcxxcx asdasdas dasdsd asdasdasdasd")
        fmt.Printf("Write More - \"%s\"
    ", b.String())
    
        /*
            //This will fix the problem
            var newBuffer bytes.Buffer
            newBuffer.WriteString(b.String())
            return newBuffer
        */
        return b
    }
    

    Playground Example

    评论

报告相同问题?

悬赏问题

  • ¥15 BV260Y用MQTT向阿里云发布主题消息一直错误
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序