Возвратите карту как «ОК» в Голанге в обычных функциях

В Go работает следующее (обратите внимание, что одно использование карты имеет один возврат, другое — два возврата)

package main

import "fmt"

var someMap = map[string]string { "some key": "hello" }

func main() {
    if value, ok := someMap["some key"]; ok {
        fmt.Println(value)
    }

    value := someMap["some key"]
    fmt.Println(value)
}

Однако я понятия не имею, как сделать то же самое с моей собственной функцией. Возможно ли иметь подобное поведение с необязательным возвратом, например map?

Например:

package main

import "fmt"

func Hello() (string, bool) {
    return "hello", true
}

func main() {
    if value, ok := Hello(); ok {
        fmt.Println(value)
    }

    value := Hello()
    fmt.Println(value)
}

Не компилируется (из-за ошибки multiple-value Hello() in single-value context) ... есть ли способ заставить этот синтаксис работать для функции Hello()?


person Michael Wasser    schedule 12.02.2015    source источник


Ответы (2)


map отличается тем, что это встроенный тип, а не функция. Две формы доступа к элементу map указаны в Спецификации языка Go: индексные выражения.

С функциями вы не можете этого сделать. Если функция имеет 2 возвращаемых значения, вы должны «ожидать» их обоих или вообще ни одного.

Однако вы можете присвоить любое возвращаемое значение пустому идентификатору:

s, b := Hello()    // Storing both of the return values

s2, _ := Hello()   // Storing only the first

_, b3 := Hello()   // Storing only the second

Вы также можете не сохранять какие-либо возвращаемые значения:

Hello()            // Just executing it, but storing none of the return values

Примечание: вы также можете присвоить оба возвращаемых значения пустому идентификатору, хотя это бесполезно (кроме проверки того, что у него ровно 2 возвращаемых значения):

_, _ = Hello()     // Storing none of the return values; note the = instead of :=

Вы также можете попробовать их на Go Playground.

Вспомогательная функция

Если вы используете его много раз и не хотите использовать пустой идентификатор, создайте вспомогательную функцию, которая отбрасывает второе возвращаемое значение:

func Hello2() string {
    s, _ := Hello()
    return s
}

И теперь вы можете сделать:

value := Hello2()
fmt.Println(value)
person icza    schedule 12.02.2015
comment
Я подозревал об этом, но не был уверен, так как у меня были проблемы с поиском документов / окончательного ответа. Спасибо и за ссылку на документы! - person Michael Wasser; 12.02.2015

В дополнение к объяснению @icza:

  • Я не рекомендую использовать вспомогательную функцию там. Особенно, если функция Hello является вашей собственной функцией.
  • Однако, если вы не можете это контролировать, можно использовать помощника.
  • Если это ваша собственная функция, лучше изменить сигнатуру вашей функции. Возможно, вы где-то ошиблись в дизайне.

Вы также можете сделать это:

package main

import "fmt"

func Hello() (string, bool) {
    return "hello", true
}

func main() {
    // Just move it one line above: don't use a short-if
    value, ok := Hello()
    if ok {
        fmt.Println(value)
    }
}
person Inanc Gumus    schedule 23.02.2019