在范围解包中有效的短变量声明

huangapple go评论141阅读模式
英文:

Valid short-variable declarations in range unpacking

问题

为什么这段代码可以运行:

package main

import "fmt"

func main() {
    myMap := map[string]int{
        "a": 1,
        "b": 1,
    }
    for k, v := range myMap {
        fmt.Println(k, v)
    }
}

但是这段代码无法编译通过:

package main

func main() {
    x := test()
}

func test() (int, int) {
    return 0, 1
}

错误信息为:

# command-line-arguments
./test.go:4: multiple-value test() in single-value context

请注意,对于数组和切片也是一样的情况:

package main

import "fmt"

func main() {
    myArray := [...]int{1, 2, 3}
    mySlice := myArray[:]
    for i := range mySlice {
        fmt.Println(i)
    }
    for i, x := range mySlice {
        fmt.Println(i, x)
    }
    for i := range myArray {
        fmt.Println(i)
    }
    for i, x := range myArray {
        fmt.Println(i, x)
    }
}

编译器是如何允许消费者选择解包 map 范围中的一个或两个返回值的?为什么语言设计者允许这样做,但对于函数的返回值却不允许呢?

英文:

Why does this code run
package main

import "fmt"

func main() {
	myMap := map[string]int{
		"a": 1,
		"b": 1,
	}
	for k, v := range myMap {
		fmt.Println(k, v)
	}
}

But this code

package main

func main() {
	x := test()
}

func test() (int, int) {
	return 0, 1
}

won't compile:

福 ~/c/p/gobook (f14d0e9)|master⚡
± : go build test.go
# command-line-arguments
./test.go:4: multiple-value test() in single-value context

Note that the same holds for arrays and slices:

package main

import "fmt"

func main() {
	myArray := [...]int{1, 2, 3}
	mySlice := myArray[:]
	for i := range mySlice {
		fmt.Println(i)
	}
	for i, x := range mySlice {
		fmt.Println(i, x)
	}
	for i := range myArray {
		fmt.Println(i)
	}
	for i, x := range myArray {
		fmt.Println(i, x)
	}
}

What is the compiler doing that allows consumers to opt-in to unpacking one or both return values in map ranges? Why did the language designers allow this for maps, slices, and arrays, but not for return values of functions?

答案1

得分: 2

你的程序期望你接受从函数test返回的两个值。实际上,你只得到了一个值。为了使这段代码工作,你只需要做一个小小的改动。

package main

func main() {
    x, _ := test()
}

func test() (int, int) {
    return 0, 1
}

在范围的情况下,显然它有多个接口。请注意,它不是一个函数,而是一个保留字。对于你的函数来说,不可能有可选的返回参数——Go语言不支持函数重载。不幸的是,这是语言所限制的(从我的角度来看,这是一件好事,因为它不会造成混淆,你总是只有一个具有唯一特定名称的方法,它总是与一个接口匹配)。

英文:

Your program expects that you're going to accept two values returned from function test. In fact you're getting only one. To make this code work you need to make only one small change.

package main

func main() {
    x,_ := test()
}

func test() (int, int) {
    return 0, 1
}

In case of ranges apparently it has multiple interfaces. Please also pay attention to the fact that it is not a function but reserved word. It is impossible to have optional returned parameters for your function - Go doesn't support functions overloading. Unfortunately this is restricted by language (from my perspective it's a good thing that you don't create confusion and you always have only one method with only one specific name that always matches only one interface).

huangapple
  • 本文由 发表于 2017年6月26日 06:22:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/44751147.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定