dpjr86761 2018-06-06 12:24
浏览 905
已采纳

golang slice [:]与最后一个元素匹配

I am working on a sample program in golang which is as follows

package main

import (
    "fmt"
)

type thing [2]byte

func walk(things []thing, idx int) []byte {
    var match []byte
    for i, thing := range things {
        if i == idx {
            match = thing[:]
        }
    }
    return match
}


func main() {
    ta := []thing{ thing{'W','A'}, thing{'O','R'} }
    m := walk(ta, 0)

    tb := []thing{ thing{'C','A'}, thing{'W','Y'}, thing{'N','V'} }
    n := walk(tb, 1)

    fmt.Printf("m = %s
", m)
    fmt.Printf("n = %s
", n)
}

The output is:

m = OR
n = NV

I am not sure why this is the case when type thing [2]byte is an array of size 2 and ta is type []thing.

Now when you write the same code as this using [][]byte

package main

import (
    "fmt"
)

func walk(things [][]byte, idx int) []byte {
    var match []byte
    for i, thing := range things {
        if i == idx {
            match = thing[:]
        }
    }
    return match
}

func main() {
    ta := [][]byte{[]byte{'W', 'A'}, []byte{'O', 'R'}}
    m := walk(ta, 0)

    tb := [][]byte{[]byte{'C', 'A'}, []byte{'W', 'Y'}, []byte{'N', 'V'}}
    n := walk(tb, 1)

    fmt.Printf("m = %s
", m)
    fmt.Printf("n = %s
", n)
}

The output is

m = WA
n = WY

I am confused by these different behaviours of slices? Printing out ta[:] when ta is type thing []byte and ta[:] when ta is [][]byte is the same

  • 写回答

2条回答 默认 最新

  • dps69208 2018-06-06 12:53
    关注

    Two cases are not the same.

    In the first case, you are working with [][2]byte (slice of arrays) not with [][]byte (slice of slices).

    var match []byte
    for i, thing := range things { // (2) change array on each iteration
        fmt.Printf("Thing %v", thing)
        if i == idx {
            match = thing[:] // (1) slice refers to array   
        }
    }
    return match // (3) here match slice refers to the last item of things
    

    One of solutions here is adding break statement after match = thing[:]. It ends the loop and match will refer to expected array.

    Just to clarify what is the actual issue here, the problem is that you are creating an slice that refers to an array that is overwritted in each n-iteration with the values of the correspondant n-th element of the slice of 2 bytes array. So if you don't stop iterating the slice will get the values of the last element.

    Using a for .. := range "hides" a little bit this fact. I guess if you write the same code with a for i;i<n;i++, you could get a better understanding of what is actually happening: https://play.golang.org/p/z3hCskZ9ezV

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

报告相同问题?