Don't Return Interfaces
Interfeys qaytarmang
"Accept Interfaces, Return Structs" darslarida ko'rgan umumiy qoidaning davomi: aksariyat holatlarda funksiyalar aniq struct qaytarishi kerak, interfeys emas. Buning ustiga, interfeys qaytarish nozik xatoga ham olib kelishi mumkin.
package main
import "fmt"
type MyError struct{ msg string }
func (e *MyError) Error() string { return e.msg }
// XAVFLI: har doim *MyError (pointer) qaytaradi
func doSomethingBad(fail bool) *MyError {
if fail {
return &MyError{msg: "ish bajarilmadi"}
}
return nil
}
func wrapper(fail bool) error {
// *MyError -> error'ga aylantirilganda, nil bo'lsa ham "bo'sh interfeys" BO'LMAYDI!
return doSomethingBad(fail)
}
func main() {
err := wrapper(false)
fmt.Println(err == nil) // kutilgan: true, lekin...
}Bu — Go'dagi mashhur "nil interfeys tuzog'i". doSomethingBad(false) nil pointer qaytaradi, lekin uni error interfeysiga aylantirganda, natija interfeys ichida **"tur: *MyError, qiymat: nil" ma'lumotini saqlaydi — bu esa haqiqiy `nil`ga teng emas! Shuning uchun funksiya to'g'ridan-to'g'ri konkret struct/pointer qaytarishi, `error` kabi interfeysga faqat haqiqatan xato bo'lganda** aylantirilishi kerak (masalan if err != nil { return err }; return nil naqshi bilan, to'g'ridan-to'g'ri emas).
>_ Exercise
Nil interfeys tuzog'idan qochib, to'g'ri naqsh bilan yozing.
- •validate(age int) *ValidationError yozing (aniq pointer qaytaradi, error emas)
- •safeValidate(age int) error yozing: agar validate natijasi nil bo'lsa aniq nil, aks holda uni qaytarsin
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
Nil pointer'ni to'g'ridan-to'g'ri interfeys sifatida qaytarish "nil interfeys tuzog'i"ga olib keladi — buning o'rniga if err != nil { return err }; return nil naqshini ishlating.
NEXT UP
Avoid Interface Pollution
$ go run main.go
Kodingizni ishga tushiring