Why map and type assertion can return 1 or 2 values?

老子叫甜甜 提交于 2020-07-02 07:36:13

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!