为什么映射和类型断言可以 return 1 或 2 个值?
Why map and type assertion can return 1 or 2 values?
要定义一个地图,我们可以做这样的事情:
value, present := m["key"]
或:
value := m["key"]
使用类型断言,我们可以:
var i interface{} = "hello"
s := i.(string)
fmt.Println(s)
s, ok := i.(string)
fmt.Println(s, ok)
但我找不到定义可以 return 1 个值或 2 个值的函数的方法。
例如:
func hello() (string, error) {
return "world", nil
}
当我调用这个函数时,我得到:
v, ok := hello() // valid
v := hello() // invalid
PS:我知道 template.Must
之类的东西是如何工作的,但它似乎有所不同。我真的很想知道 Map 和类型断言是如何发挥魔力的,所以我可以将它应用到函数中。
提前致谢。 (我清楚了吗?我的英语不好抱歉)。
映射和类型断言可以做到这一点,因为它们不是函数,而是语言的结构。规范中描述了该行为
An index expression on a map a of type map[K]V used in an assignment
or initialization of the special form
v, ok = a[x]
v, ok := a[x]
var v, ok = a[x]
yields an additional untyped boolean value. The value of ok is true if
the key x is present in the map, and false otherwise.
和
A type assertion used in an assignment or initialization of the
special form
v, ok = x.(T)
v, ok := x.(T)
var v, ok = x.(T)
yields an additional untyped boolean value. The value of ok is true if
the assertion holds. Otherwise it is false and the value of v is the
zero value for type T. No run-time panic occurs in this case.
这不是可以在一般函数上完成的事情,因此 Must
模式明确地重现了相同的行为。
The Go Programming Language Specification
A function type denotes the set of all functions with the same
parameter and result types.
FunctionType = "func" Signature .
Signature = Parameters [ Result ] .
Result = Parameters | Type .
Parameters = "(" [ ParameterList [ "," ] ] ")" .
ParameterList = ParameterDecl { "," ParameterDecl } .
ParameterDecl = [ IdentifierList ] [ "..." ] Type .
The blank identifier is represented by the underscore character _.
The blank identifier provides a way to ignore right-hand side values
in an assignment:
x, _ = f() // evaluate f() but ignore second result value
映射、类型断言和带有 range
子句的 for
语句是 Go 编程语言的特殊功能。普通函数类型不能有可变数量的 return 个值。
您可以忽略带有下划线 (_)、空白标识符的 return 值,或者您可以使用包装函数。例如,
package main
import "fmt"
func two() (int, bool) {
return 42, true
}
func one() int {
r, _ := two()
return r
}
func main() {
r, ok := two()
r, _ = two()
r = one()
fmt.Println(r, ok)
}
要定义一个地图,我们可以做这样的事情:
value, present := m["key"]
或:
value := m["key"]
使用类型断言,我们可以:
var i interface{} = "hello"
s := i.(string)
fmt.Println(s)
s, ok := i.(string)
fmt.Println(s, ok)
但我找不到定义可以 return 1 个值或 2 个值的函数的方法。
例如:
func hello() (string, error) {
return "world", nil
}
当我调用这个函数时,我得到:
v, ok := hello() // valid
v := hello() // invalid
PS:我知道 template.Must
之类的东西是如何工作的,但它似乎有所不同。我真的很想知道 Map 和类型断言是如何发挥魔力的,所以我可以将它应用到函数中。
提前致谢。 (我清楚了吗?我的英语不好抱歉)。
映射和类型断言可以做到这一点,因为它们不是函数,而是语言的结构。规范中描述了该行为
An index expression on a map a of type map[K]V used in an assignment or initialization of the special form
v, ok = a[x] v, ok := a[x] var v, ok = a[x]
yields an additional untyped boolean value. The value of ok is true if the key x is present in the map, and false otherwise.
和
A type assertion used in an assignment or initialization of the special form
v, ok = x.(T) v, ok := x.(T) var v, ok = x.(T)
yields an additional untyped boolean value. The value of ok is true if the assertion holds. Otherwise it is false and the value of v is the zero value for type T. No run-time panic occurs in this case.
这不是可以在一般函数上完成的事情,因此 Must
模式明确地重现了相同的行为。
The Go Programming Language Specification
A function type denotes the set of all functions with the same parameter and result types.
FunctionType = "func" Signature . Signature = Parameters [ Result ] . Result = Parameters | Type . Parameters = "(" [ ParameterList [ "," ] ] ")" . ParameterList = ParameterDecl { "," ParameterDecl } . ParameterDecl = [ IdentifierList ] [ "..." ] Type .
The blank identifier is represented by the underscore character _.
The blank identifier provides a way to ignore right-hand side values in an assignment:
x, _ = f() // evaluate f() but ignore second result value
映射、类型断言和带有 range
子句的 for
语句是 Go 编程语言的特殊功能。普通函数类型不能有可变数量的 return 个值。
您可以忽略带有下划线 (_)、空白标识符的 return 值,或者您可以使用包装函数。例如,
package main
import "fmt"
func two() (int, bool) {
return 42, true
}
func one() int {
r, _ := two()
return r
}
func main() {
r, ok := two()
r, _ = two()
r = one()
fmt.Println(r, ok)
}