Is it possible to conditionally implement the comma ok idiom in go, like map lookup?

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

Is it possible to conditionally implement the comma ok idiom in go, like map lookup?

问题

在Go语言中,你可以使用明显的语法从map中获取一个键的值:

someMap := map[string]string{
   //... contents
}

value := someMap["key1"]
// 如果"key1"存在于someMap中,则返回对应的值;否则返回空字符串。

问题:你无法区分缺失的键和合法的空字符串值。

因此,你可以使用逗号ok惯用法来测试键的存在性:

value, ok := someMap["key1"]
if ok {
   // 我们知道"key1"存在于map中,即使value是空字符串
} else {
   // 我们知道"key1"不存在于map中
}

这个看起来就像是map查找方法有两个不同的重载,一个只返回单个map值,另一个返回(value, bool)结果,编译器似乎根据你希望接收的返回值数量选择了相应的重载。

这非常好,我想知道是否可以在自己的函数中实现这个功能?

例如:

func fetchValue() (string, bool) {
	return "", true
}

func testMain() {
    // 这个正常工作,如预期
	val, ok := fetchValue()
	if ok {
		fmt.Println(val)
	}

    // 编译错误:赋值计数不匹配:1 = 2。
    val2 := fetchValue()
}

// 编译错误:在此包中重新声明fetchValue
func fetchValue() string {
	return ""
}

这种情况是否可行?或者这只是内置的map类型特有的秘密特殊语法?

英文:

In golang, you can fetch a key from a map using the obvious syntax:

someMap := map[string]string{
   //... contents
}

value := someMap["key1"]
// If "key1" exists in someMap, then the value will be returned; else empty string.

Problem: You can't tell missing keys apart from legitimate empty string values

So, you can test for presence using the comma ok idiom

value, ok := someMap["key1"]
if ok {
   // we know that "key1" was in the map, even if value is empty string
} else {
   // we know that "key1" was NOT in the map
}

What this looks like is that there are two different overloads of the map lookup method, one which returns just a single map value result, and one which returns the (value, bool) result, and the compiler seems to be selecting the overload based on how many return values you've said you'd like to receive.

This is quite nice, and I was wondering if it was possible to implement this on my own functions?

E.g:

func fetchValue() (string, bool) {
	return "", true
}

func testMain() {
    // This works fine, as expected
	val, ok := fetchValue()
	if ok {
		fmt.Println(val)
	}

    // COMPILE ERROR: Assignment count mismatch: 1 = 2.
    val2 := fetchValue()
}

// COMPILE ERROR: fetchValue redeclared in this package
func fetchValue() string {
	return ""
}

Is this possible? or is it secret special language sauce that only works for the builtin map type and nothing else?

答案1

得分: 2

你不能定义一个有时返回两个值,有时返回一个值的函数。

你可以这样做:

val, ok := fetchValue()
if !ok {
    // 失败的处理逻辑。
}

或者

val, _ := fetchValue()
// 不检查失败情况。
英文:

You cannot define your own function that sometimes returns 2 values, sometimes 1.

You can do:

val, ok := fetchValue()
if !ok {
    // failure path.
}

or

val, _ := fetchValue()
// not checking for failure.

huangapple
  • 本文由 发表于 2022年8月10日 17:43:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/73304063.html
匿名

发表评论

匿名网友

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

确定