Ze względu na obsługę błędów w Go często otrzymuję funkcje wielu wartości. Jak dotąd sposób, w jaki sobie z tym radziłem, był bardzo chaotyczny i szukam najlepszych praktyk pisania czystszego kodu.
Powiedzmy, że mam następującą funkcję:
type Item struct {
Value int
Name string
}
func Get(value int) (Item, error) {
// some code
return item, nil
}
Jak mogę item.Value
elegancko przypisać nową zmienną . Przed wprowadzeniem obsługi błędów moja funkcja właśnie wróciła item
i mogłem po prostu zrobić to:
val := Get(1).Value
Teraz robię to:
item, _ := Get(1)
val := item.Value
Czy nie ma sposobu na bezpośredni dostęp do pierwszej zwróconej zmiennej?
item
zwyklenil
w przypadku błędu. Bez uprzedniego sprawdzenia, czy nie wystąpił błąd, w takim przypadku kod ulegnie awarii.Odpowiedzi:
W przypadku funkcji zwracającej wielowartościowe wywołanie funkcji nie może odwoływać się do pól lub metod o określonej wartości wyniku.
A jeśli jeden z nich jest to
error
, że to nie dla rozumu (który jest funkcja może nie) i należy nie obwodnica, bo jeśli nie, twój kolejny kod może również nie zdało egzaminu (np powodując wykonawczego paniki).Jednak mogą wystąpić sytuacje, w których wiesz, że kod nie zawiedzie w żadnych okolicznościach. W takich przypadkach można zapewnić funkcję (lub metodę) pomocniczą, która odrzuci
error
(lub podniesie panikę w czasie wykonywania, jeśli nadal występuje).Może się tak zdarzyć, jeśli podasz wartości wejściowe funkcji z kodu i wiesz, że działają.
Świetnymi przykładami tego są pakiety
template
iregexp
: jeśli podasz prawidłowy szablon lub wyrażenie regularne w czasie kompilacji, możesz być pewien, że zawsze można je przeanalizować bez błędów w czasie wykonywania. Z tego powodutemplate
pakiet zapewniaMust(t *Template, err error) *Template
funkcję, aregexp
pakiet zapewniaMustCompile(str string) *Regexp
funkcję: nie zwracająerror
s, ponieważ ich zamierzone użycie jest tam, gdzie dane wejściowe są gwarantowane.Przykłady:
Wracając do twojej sprawy
JEŚLI możesz być pewien,
Get()
że nie wygenerujeerror
pewnych wartości wejściowych, możesz utworzyć funkcję pomocniczą,Must()
która nie zwróci,error
ale wywoła panikę w czasie wykonywania, jeśli nadal występuje:Ale nie powinieneś tego używać we wszystkich przypadkach, tylko wtedy, gdy masz pewność, że się powiedzie. Stosowanie:
Alternatywa / uproszczenie
Możesz nawet jeszcze bardziej to uprościć, jeśli włączysz
Get()
wywołanie do funkcji pomocniczej, nazwijmy toMustGet
:Stosowanie:
Zobacz kilka interesujących / powiązanych pytań:
jak analizować wielokrotne zwroty w golang
Zwróć mapę jak „ok” w Golang na normalnych funkcjach
źródło
Nie, ale to dobrze, ponieważ zawsze powinieneś radzić sobie z błędami.
Istnieją techniki, które możesz zastosować, aby odroczyć obsługę błędów, zobacz Błędy to wartości Roba Pike'a.
W tym przykładzie z wpisu na blogu ilustruje, w jaki sposób można utworzyć
errWriter
typ, który odracza obsługę błędów, dopóki nie skończysz dzwonićwrite
.źródło
Tak jest.
Zaskakujące, co? Możesz uzyskać określoną wartość z wielokrotnego zwrotu za pomocą prostej
mute
funkcji:https://play.golang.org/p/IwqmoKwVm-
Zwróć uwagę, jak wybierasz numer wartości, tak jak w przypadku wycinka / tablicy, a następnie typ, aby uzyskać rzeczywistą wartość.
Możesz przeczytać więcej o nauce stojącej za tym z tego artykułu . Podziękowania dla autora.
źródło
Nie, nie możesz bezpośrednio uzyskać dostępu do pierwszej wartości.
Przypuszczam, że dobrym pomysłem byłoby zwrócenie tablicy wartości zamiast „item” i „err”, a następnie zrobienie tego,
item, _ := Get(1)[0]
ale nie polecam tego.źródło
A może w ten sposób?
źródło