GoDasturchi
Accept Interfaces, Return Structs Part 2: When to Break the Rules

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.

example.go
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.

Hints (0/3)

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

OUTPUT

$ go run main.go
Kodingizni ishga tushiring

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.

example.go
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.

Hints (0/3)

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