处理函数

时间:2018-04-27 12:18:55

标签: string go call slice

在下一个代码中,第一个Println在构建时失败,错误为slice of unaddressable value。其余的线路都很好。

package main

import "fmt"

func getSlice() [0]int {
   return [...]int{}
}

func getString() string {
   return "hola"
}

func main() {
    fmt.Println(getSlice()[:]) // Error: slice of unaddressable value

    var a = getSlice()
    fmt.Println(a[:])

    fmt.Println(getString()[:])

    var b = getString()
    fmt.Println(b[:])
}

Try this code

如果第一个Println被评论,则可行。 Try it out

为什么?我在这里缺少什么?

2 个答案:

答案 0 :(得分:3)

您缺少的是切片数组时,操作数必须是可寻址的([0]int是数组,而不是切片)。并且函数调用的返回值不可寻址。有关详细信息,请参阅How can I store reference to the result of an operation in Go?;和"cannot take the address of" and "cannot call pointer method on"

Spec: Slice expressions:

  

如果切片操作数是一个数组,则它必须是addressable,并且切片操作的结果是一个与数组具有相同元素类型的切片。

在这个表达式中:

getSlice()[:]

getSlice()会返回数组,因为它是函数调用的结果,所以它不可寻址。因此你无法切片。

在这个表达式中:

getString()[:]

getString()返回string值,因此即使该值不可寻址也可以进行切片。这是允许的,因为切片表达式的结果将是另一个string,并且Go中的string值是不可变的。

此外,变量为addressable,因此这将始终有效:

var a = getSlice()
fmt.Println(a[:])

答案 1 :(得分:1)

getSlice()没有返回一个切片,它返回一个不可寻址的数组。您可以返回指向数组的指针:

func getSlice() *[0]int {
   return &[...]int{}
}

或保留getSlice(),并将结果放在临时变量中:

t := getSlice()
fmt.Println(t[:])