寻址函数返回的切片时出错

edu*_*upo 0 string call go 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[:])
}
Run Code Online (Sandbox Code Playgroud)

试试这个代码

如果第一个Println被评论它就有效。 试试看

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

icz*_*cza 5

您缺少的是,在对数组进行切片时,操作数必须是可寻址的([0]int是数组,而不是切片)。并且函数调用的返回值是不可寻址的。有关详细信息,请参阅如何在 Go 中存储对操作结果的引用?; 和“不能获取地址”和“不能调用指针方法”

规格:切片表达式:

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

在这个表达式中:

getSlice()[:]
Run Code Online (Sandbox Code Playgroud)

getSlice()返回一个数组,由于它是函数调用的结果,因此它是不可寻址的。因此你不能切片它。

在这个表达式中:

getString()[:]
Run Code Online (Sandbox Code Playgroud)

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

另外,变量是可寻址的,所以这总是有效的:

var a = getSlice()
fmt.Println(a[:])
Run Code Online (Sandbox Code Playgroud)