切片golang切片

时间:2015-04-07 13:12:14

标签: go slice

问题是我是片bar。我想用bar的前两个元素创建另一个slice foo;如果bar中至少有2个元素,或者bar中的第一个元素,如果bar至少有一个元素。

我的想法:

// bar := []int{1, 2, 3...
foo := bar[:(int)(math.Min(float64(len(bar)), 2))]

修改 这是我尝试的另一种方式,

x := 2
if len(bar) < 2 {
    x = len(bar)
}
foo := bar[:x]

是否可以改进代码?至少,铸造两次以实现这么简单的事情对我来说并不好看。

5 个答案:

答案 0 :(得分:6)

如果切片的长度大于2 ,则可以重新切片。如果没有,无需重新分配,只需在分配中使用切片,这将自动满足您的需求:结果最多可包含2个元素。

您甚至可以“备用”else的{​​{1}}分支:

if

注意:

切片是参考类型。因此,即使您使用foo := bar if len(foo) > 2 { foo = foo[:2] } 初始化bar,如果之后修改foo 变量(不是切片的元素),也不会影响foo {1}}(分配时复制参考值):

bar

输出(在Go Playground上尝试):

bar := []int{0, 1, 2, 3}
foo := bar
if len(foo) > 2 {
    foo = foo[:2]
}
fmt.Println(foo) // Here foo is [0, 1] as expected

foo = foo[:1]    // Reslicing foo
fmt.Println(bar) // Bar is unaffected, bar = [0 1 2 3]

答案 1 :(得分:3)

只需使用if即可。它具有更高的可读性和高性能,因为intfloat64之间没有转化。

var foo []int
if len(bar) > 1 {
    foo = bar[:2]
} else {
    foo = bar[:len(bar)]
}

答案 2 :(得分:1)

Go没有math.MinInt。但实施一个就像:

func Min(x, y int) int {
    if x < y {
        return x
    }
    return y
}

...

foo := bar[:Min(len(bar), 2)]

答案 3 :(得分:0)

bar := []int{}
n := len(bar)
if n > 2 {
    n = 2
}
foo := bar[:n]
fmt.Printf("%v", foo)

使用len(bar)= 0,1,2,n .. Playground sample

答案 4 :(得分:0)

一般(在评论中提出)函数可以使用任意数量的元素:

func strip(s []int, n int) []int {
    if len(s) < n {
        n = len(s)
    }
    return s[:n]
}

...
foo := strip(bar, 2)

Go Playground example