问题
To define a map, we can do such a thing:
value, present := m["key"]
or:
value := m["key"]
and with type assertion, we can do:
var i interface{} = "hello"
s := i.(string)
fmt.Println(s)
s, ok := i.(string)
fmt.Println(s, ok)
but I can't find a way to define a func that can return 1 value or 2-values.
For instance:
func hello() (string, error) {
return "world", nil
}
When I invoke this func I get:
v, ok := hello() // valid
v := hello() // invalid
PS: I know how something like template.Must
works, but it seems different. I really want to know how Map and type assertion can do the magic, so I can apply it to functions.
Thanks in advance. (Am I clear? I have poor English sorry).
回答1:
The Go Programming Language Specification
Function types
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 .
Blank identifier
The blank identifier is represented by the underscore character _.
Assignments
The blank identifier provides a way to ignore right-hand side values in an assignment:
x, _ = f() // evaluate f() but ignore second result value
Maps, type assertions, and the for
statement with a range
clause are special features of the Go programming language. You can't have a variable number of return values for an ordinary function type.
You can ignore a return value with an underscore (_), the blank identifier, or you can use a wrapper function. For example,
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)
}
回答2:
Map and type assertions can do this because they are not functions, but structures of the language. The behavior is described in the spec
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.
and
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.
It is not something that can be done on general functions, hence the Must
pattern that explicitely reproduce the same behavior.
来源:https://stackoverflow.com/questions/36244725/why-map-and-type-assertion-can-return-1-or-2-values