Возврат карты как "хорошо" в Голанге на нормальных функциях
В 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()
?
1 ответ
map
отличается, потому что это встроенный тип, а не функция. 2 формы доступа к элементу 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.
Вспомогательная функция
Если вы используете его много раз и не хотите использовать пустой идентификатор, создайте вспомогательную функцию, которая отбрасывает второе возвращаемое значение:
func Hello2() string {
s, _ := Hello()
return s
}
И теперь вы можете сделать:
value := Hello2()
fmt.Println(value)
В дополнение к объяснению @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)
}
}