Accept Interfaces, Return Structs Part 2: When to Break the Rules
Interfeys qabul qiling, struct qaytaring 2-qism: qoidani qachon buzish kerak
Har qanday qoida kabi, bunisi ham mutlaq emas. Ba'zan funksiya ataylab interfeys qaytaradi — bu qoidani buzish emas, balki to'g'ri vaziyatda to'g'ri vositani tanlash.
package main
import (
"fmt"
"io"
"strings"
)
// Bu funksiya ataylab io.Reader qaytaradi, chunki:
// 1. Chaqiruvchiga ICHKI turning o'zi umuman kerak emas, faqat "o'qish qobiliyati"
// 2. Kelajakda ichki implementatsiyani (masalan fayldan o'qishga) o'zgartirish mumkin,
// chaqiruvchi kodini buzmasdan
func NewGreetingReader(name string) io.Reader {
return strings.NewReader("Salom, " + name + "!")
}
func main() {
r := NewGreetingReader("Dunyo")
data, _ := io.ReadAll(r)
fmt.Println(string(data))
}Bu yerda NewGreetingReader io.Reader interfeysini qaytaradi, aniq *strings.Reader turini emas. Nega? Chunki chaqiruvchiga faqat "bu narsadan o'qish mumkin" degan qobiliyat kerak — ichki qanday amalga oshirilgani (matn, fayl, tarmoq) muhim emas. Bu qachon to'g'ri: implementatsiya detalini ataylab yashirmoqchi bo'lganingizda, yoki kelajakda uni almashtirishni rejalashtirsangiz. "Real-World Patterns" kursida ko'rgan io.Reader/io.Writer ham aynan shu sabab bilan interfeys sifatida qaytariladi va qabul qilinadi.
>_ Exercise
Ataylab error interfeysini qaytaring.
- •validateAge(age int) error yozing: age < 0 bo'lsa xato qaytarsin, aks holda nil
- •ikki holat uchun chaqirib, natijalarni chop eting
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
Implementatsiya detalini ataylab yashirish kerak bo'lganda (masalan error, io.Reader), interfeys qaytarish to'g'ri va keng tarqalgan tanlov.
NEXT UP
Avoid Else After Return
$ go run main.go
Kodingizni ishga tushiring