Devido ao tratamento de erros no Go, muitas vezes acabo com funções de vários valores. Até agora, a maneira como gerenciei isso tem sido muito confusa e estou procurando as melhores práticas para escrever um código mais limpo.
Digamos que eu tenha a seguinte função:
type Item struct {
Value int
Name string
}
func Get(value int) (Item, error) {
// some code
return item, nil
}
Como posso atribuir uma nova variável a item.Value
elegantemente. Antes de introduzir o tratamento de erros, minha função acabou de retornar item
e eu poderia simplesmente fazer isso:
val := Get(1).Value
Agora eu faço isso:
item, _ := Get(1)
val := item.Value
Não existe uma maneira de acessar diretamente a primeira variável retornada?
go
error-handling
return-value
multiple-return-values
Spearfisher
fonte
fonte
item
normalmente ocorreránil
em caso de erro. Sem verificar se há um erro primeiro, seu código irá travar nesse caso.Respostas:
No caso de uma função de retorno de vários valores, você não pode se referir a campos ou métodos de um valor específico do resultado ao chamar a função.
E se um deles for um
error
, ele está lá por um motivo (que é a função pode falhar) e você não deve ignorá-lo porque, se o fizer, seu código subsequente também pode falhar miseravelmente (por exemplo, resultando em pânico no tempo de execução).No entanto, pode haver situações em que você sabe que o código não falhará em nenhuma circunstância. Nesses casos, você pode fornecer uma função auxiliar (ou método) que descartará o
error
(ou gerará um pânico de tempo de execução, se ainda ocorrer).Esse pode ser o caso se você fornecer os valores de entrada para uma função a partir do código e souber que eles funcionam.
Ótimos exemplos disso são os pacotes
template
eregexp
: se você fornecer um modelo ou regexp válido em tempo de compilação, você pode ter certeza de que eles sempre podem ser analisados sem erros em tempo de execução. Por esse motivo, otemplate
pacote fornece aMust(t *Template, err error) *Template
função e oregexp
pacote fornece os s, porque o uso pretendido é onde a entrada tem garantia de validade.MustCompile(str string) *Regexp
função: eles não retornamerror
Exemplos:
De volta ao seu caso
SE você tiver certeza de
Get()
que não produziráerror
para determinados valores de entrada, pode criar umaMust()
função auxiliar que não retornaria o,error
mas geraria um pânico de tempo de execução se ainda ocorrer:Mas você não deve usar isso em todos os casos, apenas quando tiver certeza de que funciona. Uso:
Alternativa / Simplificação
Você pode até simplificar ainda mais se incorporar a
Get()
chamada à sua função auxiliar, vamos chamá-laMustGet
:Uso:
Veja algumas questões interessantes / relacionadas:
como analisar retornos múltiplos em golang
Retorna o mapa como 'ok' no Golang nas funções normais
fonte
Não, mas isso é bom, pois você deve sempre lidar com seus erros.
Existem técnicas que você pode empregar para adiar o tratamento de erros, consulte Erros são valores de Rob Pike.
Neste exemplo da postagem do blog, ele ilustra como você pode criar um
errWriter
tipo que adia o tratamento de erros até terminar de chamarwrite
.fonte
Sim existe.
Surpreendente, hein? Você pode obter um valor específico de um retorno múltiplo usando uma
mute
função simples :https://play.golang.org/p/IwqmoKwVm-
Observe como você seleciona o número do valor exatamente como faria em uma fatia / matriz e, em seguida, o tipo para obter o valor real.
Você pode ler mais sobre a ciência por trás disso neste artigo . Créditos ao autor.
fonte
Não, você não pode acessar diretamente o primeiro valor.
Suponho que um hack para isso seria retornar uma matriz de valores em vez de "item" e "err", e então apenas fazer,
item, _ := Get(1)[0]
mas eu não recomendaria isso.fonte
Que tal assim?
fonte