duandai0373 2018-08-22 14:16
浏览 118
已采纳

Go中的bytes.String()与bytes.Bytes()

Consider a text file like this:

Some text
here.
---
More text
another line.
---
Third part of text.

I want to split it into three parts, divided by the --- separator. The parts should be stored in a map.

Now, the exact same programs with different types.

When I use string, everything works fine:

KEY: 0
Some text
here.
KEY: 1
More text
another line.
KEY: 2
Third part of text.

https://play.golang.org/p/IcGdoUNcTEe

When I use []byte, things gets messed up:

KEY: 0
Third part of teKEY: 1
Third part of text.
ne.
KEY: 2
Third part of text.

https://play.golang.org/p/jqLhCrqsvOs

Why?


Program 1 (string):

func main() {
    parts := parseParts([]byte(input))

    for k, v := range parts {
        fmt.Printf("KEY: %d
%s", k, v)
    }
}

func parseParts(input []byte) map[int]string {
    parts := map[int]string{}
    s := bufio.NewScanner(bytes.NewReader(input))
    buf := bytes.Buffer{}
    i := 0
    for s.Scan() {
        if s.Text() == "---" {
            parts[i] = buf.String()
            buf.Reset()
            i++
            continue
        }
        buf.Write(s.Bytes())
        buf.WriteString("
")
    }
    parts[i] = buf.String()
    return parts
}

Program 2 ([]byte):

func main() {
    parts := parseParts([]byte(input))

    for k, v := range parts {
        fmt.Printf("KEY: %d
%s", k, v)
    }
}

func parseParts(input []byte) map[int]string {
    parts := map[int]string{}
    s := bufio.NewScanner(bytes.NewReader(input))
    buf := bytes.Buffer{}
    i := 0
    for s.Scan() {
        if s.Text() == "---" {
            parts[i] = buf.String()
            buf.Reset()
            i++
            continue
        }
        buf.Write(s.Bytes())
        buf.WriteString("
")
    }
    parts[i] = buf.String()
    return parts
}

展开全部

  • 写回答

2条回答 默认 最新

  • donglu1971 2018-08-22 14:43
    关注

    In the string version,

    parts[i] = buf.String()
    

    sets parts[i] to a new string every time. In the []byte version,

    parts[i] = buf.Bytes()
    

    sets parts[i] to a byte slice backed by the same array every time. The contents of the backing array are the same for all three slices, but the lengths match the length when created, which is why all three slices show the same content but cut off at different places.

    You could replace the byte slice line

    parts[i] = buf.Bytes()
    

    with something like this:

    bb := buf.Bytes()
    b := make([]byte, len(bb))
    copy(b, bb)
    parts[i] = b
    

    in order to get the behavior to match the string version. But the string version is easier and better matches what you seem to be trying to do.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部