рдиреАрд▓ рд╣рдореЗрд╢рд╛ рд╢реВрдиреНрдп рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ

рдиреАрд▓ рд╣рдореЗрд╢рд╛ рд╢реВрдиреНрдп рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ


"рдХреНрдпрд╛? рдпрд╣рд╛рдБ рдХреНрдпрд╛ рд▓рд┐рдЦрд╛ рд╣реИ?" рддреБрдо рдкреВрдЫрддреЗ рд╣реЛред рдЕрдм рдореИрдВ рдЗрд╕реЗ рдмрд╛рд╣рд░ рд░рдЦ рджреВрдВрдЧрд╛ред


рдЬрдм рдореИрдВрдиреЗ рднрд╛рд╖рд╛ рд╕реАрдЦрдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛, рддреЛ рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрд╛ рдХрд┐ рдореИрдВ рдЗрд╕ рд╕рдВрдХреАрд░реНрдг рдорд╛рдорд▓реЗ рдореЗрдВ рдЖрдКрдВрдЧрд╛ред рдПрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╕рдВрдЧреНрд░рд╣ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдирд╛ рднреА рддрд░реНрдХрд╕рдВрдЧрдд рдирд╣реАрдВ рд╣реИред


рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

func Foo() error { var err *os.PathError = nil return err } func main() { err := Foo() fmt.Println(err) // <nil> fmt.Println(err == nil) // false } 

WAT!


рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреНрдпрд╛ рд╣реИ?

Go runtime / runtime2.go рдкреИрдХреЗрдЬ рдлрд╝рд╛рдЗрд▓ рдкрд░ рдЬрд╛рдПрдВ рдФрд░ рджреЗрдЦреЗрдВ:


 type itab struct { // 40 bytes on a 64bit arch inter *interfacetype _type *_type ... } 

рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдкреНрд░рдХрд╛рд░ рдФрд░ рдореВрд▓реНрдп рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдЦреБрдж рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИред


рдХрд┐рд╕реА рднреА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдореВрд▓реНрдп, рди рдХрд┐ рдХреЗрд╡рд▓ рддреНрд░реБрдЯрд┐, рдорд╛рдорд▓реЗ рдореЗрдВ рд╢реВрдиреНрдп рд╣реИ рдЬрдм AND рдФрд░ рдорд╛рди рд╢реВрдиреНрдп рд╣реЛрддреЗ рд╣реИрдВред


рдлреВ рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рдХрд╛рд░ рдХрд╛ рдУрдПрд╕ рд░рд┐рдЯрд░реНрди рдХрд░рддрд╛ рд╣реИ * os.PathError, рд╣рдо рдкрд░рд┐рдгрд╛рдо рдХреА рддреБрд▓рдирд╛ рдЯрд╛рдЗрдк рдПрдирдЖрдИрдПрд▓ рдХреЗ рд╢реВрдиреНрдп рд╕реЗ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рдЙрдирдХреА рдЕрд╕рдорд╛рдирддрд╛ рдХрд╛ рдкрд╛рд▓рди рд╣реЛрддрд╛ рд╣реИред


рд╢рд╛рдпрдж рдмрд╣реБрдд рд╕реЗ рд▓реЛрдЧ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирддреЗ рдереЗ, рд▓реЗрдХрд┐рди рдХрдо рд╣реА рд▓реЛрдЧ рд╕реЛрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдХреИрд╕реЗ рд▓рд╛рдпрд╛ рдЬрд╛рдПред


рдореЗрд░рд╛ рдЙрджрд╛рд╣рд░рдг рд╣реИ

 type Response struct { Result ResponseResult `json:"result,omitempty"` Error *ResponseError `json:"error,omitempty"` } type ResponseError struct { Message string `json:"message"` } func (e *ResponseError) Error() string { return e.Message } ... func (s *NotificationService) NotifyIfError(w *ResponseWriter) error { ... var res handlers.Response _ = json.Unmarshal(body, &res) if res.Error == nil { return } return s.NotifyError(err) } 

рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╣рдореЗрд╢рд╛ рдПрдХ рдкрд░рд┐рдгрд╛рдо рдпрд╛ рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИред


рдпрджрд┐ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рдЕрдзрд┐рд╕реВрдЪрдирд╛ рд╕реЗрд╡рд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдиреЗ рдкрд░ рднреЗрдЬрддреЗ рд╣реИрдВред
рд╕реЗрд╡рд╛ рдХреЗ рдЕрдВрджрд░, рддреНрд░реБрдЯрд┐ рд╡рд┐рдзрд┐ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░рд╛ рдореВрд▓реНрдп рд╢реВрдиреНрдп рд╣реИ, рд╣рдореЗрдВ рдШрдмрд░рд╛рд╣рдЯ рд╣реЛрддреА рд╣реИред


рдХреНрдпрд╛ рдХрд░реЗрдВ?

рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╕рдЦреНрддреА рд╕реЗ рдПрдХ рдЗрдВрдЯрд░рдлреЗрд╕ рд▓реМрдЯреЗрдВред


рддреНрд░реБрдЯрд┐ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ - рддреНрд░реБрдЯрд┐ рдХрд╛ рдкреНрд░рдХрд╛рд░ред


  • рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рддреНрд░реБрдЯрд┐ рдХреА рдШреЛрд╖рдгрд╛ рдЬреЛрдбрд╝реЗрдВ

 func (s *NotificationService) NotifyIfError(w *ResponseWriter) error { ... var res Response _ = json.Unmarshal(body, &res) var err error = res.Error return s.NotifyError(err) } 

рдпрд╣ рддрдХрдиреАрдХ, рдореЗрд░реЗ рдЖрд╢реНрдЪрд░реНрдп рдХреЗ рд▓рд┐рдП, рдпрд╛ рддреЛ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреА рд╣реИред


рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рдЬрдм рдЧрд▓рдд рдЪрд░ рдХрд╛ рдорд╛рди рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдЯрд╛рдЗрдк рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рд╢реВрдиреНрдп рдирд╣реАрдВ рд╣реИред


  • рдЖрдЗрдП рд╣рдорд╛рд░реЗ рд╕реНрд░реЛрдд рдкреНрд░рдХрд╛рд░ рдХреЛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ рдФрд░ рдЗрд╕рдХреЗ рдореВрд▓реНрдп рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВред

 func (s *NotificationService) NotifyIfError(w *ResponseWriter) error { ... if e, ok := err.(*ResponseError); ok && e == nil { return s.NotifyError(err) } return nil } 

рд╣рд╛рдВ, рдпрд╣ рддрдХрдиреАрдХ рдХрд╛рдо рдХрд░рддреА рд╣реИред


рд▓реЗрдХрд┐рди рдИрдорд╛рдирджрд╛рд░ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЙрди рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХрд╛ рдЬреЛрдЦрд┐рдо рдирд╣реАрдВ рдЙрдард╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рд╕рдВрдЪрд╛рд░рд┐рдд рдХрд░реЗрдВрдЧреЗред


рдпрд╣ рдбреЗрдЯрд╛рдмреЗрд╕ рдбреНрд░рд╛рдЗрд╡рд░, рд╣рдорд╛рд░реЗ рд╕рднреА рдЖрдВрддрд░рд┐рдХ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдФрд░ рдЕрдиреНрдп рдХрдЪрд░реЗ рд╕реЗ рд╕рднреА рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВред


рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рджреЗрдЦреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕рдмрд╕реЗ рддрд░реНрдХрд╕рдВрдЧрдд рд╡рд┐рдХрд▓реНрдк рдХреНрдпрд╛ рд╣реИ:

 func (s *NotificationService) NotifyIfError(w *ResponseWriter) error { var err error ... var res Response _ = json.Unmarshal(body, &res) if res.Error != nil { return s.NotifyError(err) } return nil } 

рдкрд╣рд▓реЗ, рд╣рдордиреЗ рдЯрд╛рдЗрдк рддреНрд░реБрдЯрд┐ рдХрд╛ рдПрдХ рдЪрд░ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдорд╛рди рдФрд░ рдкреНрд░рдХрд╛рд░ рдПрдирдЖрдИрдПрд▓ рдХреЗ рд╕рд╛рде рдирд┐рдХрд▓рд╛ред
рдФрд░ рдЗрд╕ рдЪрд░ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдкреНрд░рдХрд╛рд░ рдФрд░ рдореВрд▓реНрдп рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП nil рдкрд░ рд╣рдорд╛рд░реЗ рдкреНрд░рдХрд╛рд░ рдФрд░ рдЙрд╕рдХреЗ рдореВрд▓реНрдп рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВред


рдпрд╣ рд╣рдореЗрдВ рдШрдмрд░рд╛рд╣рдЯ рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рдЖрдиреЗ рджреЗрдЧрд╛ред


рдЕрдВрдд рдореЗрдВ

рдЖрдк рдЖрдЧреЗ рднреА рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╕рд╛рде "рд╡реИрдХрд▓реНрдкрд┐рдХ" рддреНрд░реБрдЯрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, OptionalError рдпрд╛ ErrorOrNil рдкреНрд░рдХрд╛рд░, рдЬреИрд╕реЗ:


 func (r *Response) ErrorOrNil() error { if r.Error == nil { return nil } return r.Error } 

рдЯрд┐рдкреНрдкрдгреА

рдЧреЛ рд╡рд┐рдХреА рдиреЛрдЯреЛрдВ рдореЗрдВ, рдХреЛрдб рдХреА рд╕рдореАрдХреНрд╖рд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╡рд┐рд╖рдп рдореЗрдВ рдПрдХ рдиреЛрдЯ рд╣реИ: рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдПрдХ рдареЛрд╕ рдкреНрд░рдХрд╛рд░ рд▓реМрдЯрд╛рдПрдВ рдФрд░ рдЙрдкрднреЛрдХреНрддрд╛ рдХреЛ рдирд┐рд░реНрдорд╛рддрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдордЬрд╛рдХ рдЙрдбрд╝рд╛рдПрдВред


рдореИрдВ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЙрдкрд░реЛрдХреНрдд рдиреГрддреНрдп рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╣реИрдВред


рдореЗрд░реЗ рдиреЛрдЯреНрд╕ рдЖрдкрдХреЛ рдПрдХ рджрд╣рд╢рдд рдореЗрдВ рдирд╣реАрдВ рдЖрдиреЗ рджреЗрддреЗ рд╣реИрдВ рдЬрдм рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рдмреНрдпрд╛рдЬ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдФрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЖрдк рд╣рдореЗрд╢рд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред


рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд░рдХрд╛рд░ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХрд╛ рдЬреЛрдЦрд┐рдо рдЙрдард╛ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдЙрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрдВред


рд╕рдВрджрд░реНрдн

рдЬрд╛рдиреЗ-internals


рдореИрдВ рд╣реВрдВ

рд▓рд┐рдВрдХреНрдбрдЗрди
рддрд╛рд░
рдЪрд╣рдЪрд╣рд╛рдирд╛
Github

Source: https://habr.com/ru/post/hi449714/


All Articles