Из-за обработки ошибок в Go я часто получаю функции с несколькими значениями. До сих пор я с этим справлялся очень запутанно, и я ищу лучшие практики для написания более чистого кода.
Скажем, у меня есть следующая функция:
type Item struct {
Value int
Name string
}
func Get(value int) (Item, error) {
// some code
return item, nil
}
Как мне item.Value
элегантно присвоить новую переменную . Перед тем, как представить обработку ошибок, моя функция только что вернулась, item
и я мог просто сделать это:
val := Get(1).Value
Теперь делаю так:
item, _ := Get(1)
val := item.Value
Разве нет возможности напрямую получить доступ к первой возвращаемой переменной?
go
error-handling
return-value
multiple-return-values
Подводный охотник
источник
источник
item
обычно будетnil
в случае ошибки. Без предварительной проверки ошибки ваш код в этом случае выйдет из строя.Ответы:
В случае функции возврата с несколькими значениями вы не можете ссылаться на поля или методы определенного значения результата при вызове функции.
И если один из них является
error
, он существует по какой-то причине (функция может выйти из строя), и вы не должны обходить его, потому что, если вы это сделаете, ваш последующий код также может потерпеть неудачу (например, привести к панике во время выполнения).Однако могут быть ситуации, когда вы знаете, что код не выйдет из строя ни при каких обстоятельствах. В этих случаях вы можете предоставить вспомогательную функцию (или метод), которая отменит
error
(или вызовет панику во время выполнения, если она все еще возникает).Это может быть так, если вы предоставляете входные значения для функции из кода и знаете, что они работают.
Великие примеры этого являются
template
иregexp
пакеты: если вы предоставить действительный шаблон или регулярное выражение во время компиляции, вы можете быть уверены , что они всегда могут быть разобраны без ошибок во время выполнения. По этой причинеtemplate
пакет предоставляетMust(t *Template, err error) *Template
функцию, аregexp
пакет предоставляетMustCompile(str string) *Regexp
функцию: они не возвращаютerror
s, потому что их предполагаемое использование - это то, где гарантированно будет действительный ввод.Примеры:
Вернемся к твоему делу
ЕСЛИ вы можете быть уверены,
Get()
что не будет производитьerror
для определенных входных значений, вы можете создать вспомогательнуюMust()
функцию, которая не будет возвращать,error
но вызывает панику во время выполнения, если она все еще возникает:Но вы не должны использовать это во всех случаях, только когда вы уверены, что это удастся. Использование:
Альтернатива / упрощение
Вы можете даже упростить его, если включите
Get()
вызов в свою вспомогательную функцию, назовем ееMustGet
:Использование:
См. Некоторые интересные / связанные вопросы:
как разобрать несколько возвратов в голанге
Вернуть карту как 'ok' в Golang для обычных функций
источник
Нет, но это хорошо, так как вы всегда должны обрабатывать свои ошибки.
Есть методы, которые можно использовать для отсрочки обработки ошибок, см. Роб Пайк , « Ошибки - это значения ».
В этом примере из сообщения в блоге он показывает, как можно создать
errWriter
тип, который откладывает обработку ошибок до завершения вызоваwrite
.источник
Да, есть.
Удивительно, да? Вы можете получить конкретное значение из множественного возврата, используя простую
mute
функцию:https://play.golang.org/p/IwqmoKwVm-
Обратите внимание, как вы выбираете номер значения, как если бы вы выбирали из среза / массива, а затем тип, чтобы получить фактическое значение.
Вы можете узнать больше о науке, стоящей за этим, из этой статьи . Кредиты автору.
источник
Нет, вы не можете напрямую получить доступ к первому значению.
Я полагаю, что взломом для этого было бы возвращение массива значений вместо «item» и «err», а затем просто так,
item, _ := Get(1)[0]
но я бы не рекомендовал этого.источник
Как насчет этого?
источник