Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Writing "append(s, ...)" instead of "s = append(s, ...)" results in a compiler error because it is an unused expression. I'm not sure how a newbie could make this mistake since that code doesn't compile.




Indeed the usual error is

    b := append(a, …)

How is that an error if b is properly referenced? It’s perhaps a waste of memory but not wrong

Because `append` works in-place, Go slices are amortised, and the backing buffer is shared between `a` and `b`, so unless you never ever use a again it likely will have strange effects e.g.

    a := make([]int, 0, 5)
    a = append(a, 0, 0)
    b := append(a, 1)
    a = append(a, 0)
    fmt.Println(b)
prints

    [0 0 0]
because the following happens:

    a := make([]int, 0, 5)
    // a = [() _ _ _ _ _]
    // a has length 0 but the backing buffer has capacity 5, between the parens is the section of the buffer that's currently part of a, between brackets is the total buffer
    a = append(a, 0, 0)
    // a = [(0 0) _ _ _]
    // a now has length 2, with the first two locations of the backing buffer zeroed
    b := append(a, 1)
    // b = [(0 0 1) _ _]
    // b has length 3, because while it's a different slice it shares a backing buffer with a, thus while a does not see the 1 it is part of its backing buffer:
    // a  = [(0 0) 1 _ _]
    a = append(a, 0)
    // append works off of the length, so now it expands `a` and writes at the new location in the backing buffer
    // a = [(0 0 0) _ _]
    // since b still shares a backing buffer...
    // b = [(0 0 0) _ _]

Thanks for the thorough explanation!



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: