4. Interfeyslar
Go'da interfeys yashirin (implicit) amalga oshiriladi: tur kerakli metodlarga ega bo'lsa, u interfeysni qanoatlantiradi. Masalalarda kichik interfeyslar va ularning kombinatsiyasiga e'tibor bering.
Asoslar
1. Shape interfeysini (Area() float64, Perimeter() float64) e'lon qiling va uni Circle, Rectangle, Triangle turlari uchun amalga oshiring. []Shape dagi figuralarning umumiy yuzasini hisoblang.
Misol: Circle{R: 1}, Rectangle{3, 4}, Triangle{3, 4, 5} → yuzalari 3.1416, 12, 6; umumiy yuza 21.1416
2. Shape slice'ini yuzasi bo'yicha sort.Slice bilan saralang, so'ng xuddi shuni sort.Interface (Len, Less, Swap) ni amalga oshiruvchi ByArea turi bilan bajaring.
Misol: yuzalar 12, 3.1416, 6 → saralangan: Circle, Triangle, Rectangle (ikkala usulda bir xil)
3. Qiymat va ko'rsatkich qabul qiluvchili metodlar interfeysni qanoatlantirishga qanday ta'sir qilishini ko'rsating: *T da metodi bor turning T qiymati nega interfeysga o'zlashtirilmasligini tajriba bilan tushuntiring.
Misol: func (c *Circle) Area() bo'lsa, var s Shape = Circle{} — kompilyatsiya xatosi; var s Shape = &Circle{} ishlaydi
4. Kompilyatsiya vaqtida tur interfeysni qanoatlantirishini tekshiruvchi var _ Shape = (*Circle)(nil) ifodasini qo'llang va metod olib tashlanganda nima bo'lishini ko'rsating.
Misol: var _ Shape = (*Circle)(nil) — Perimeter metodi o'chirilsa, kompilyatsiya xatosi: *Circle does not implement Shape (missing method Perimeter)
5. fmt.Stringer ni Point, Matrix va Weekday turlari uchun amalga oshiring va fmt.Println natijasini solishtiring.
Misol: Point{1, 2} → (1, 2); Weekday(1) → Dushanba
Bo'sh interfeys va tur tekshiruvi
6. []any slice'ida turli turdagi qiymatlar berilgan. type switch yordamida har birining turini va qiymatini chiqaring (int, string, []int, error, nil va boshqalar).
Misol: []any{42, "salom", []int{1, 2}, errors.New("xato"), nil, 3.14} → int: 42, string: salom, []int: [1 2], error: xato, nil, float64: 3.14
7. Tur tasdiqlash (v, ok := x.(T)) va uning ok siz varianti orasidagi farqni ko'rsating: noto'g'ri turda qaysi biri panic beradi?
Misol: var x any = "salom": n, ok := x.(int) → 0 false; n := x.(int) → panic: interface conversion: interface {} is string, not int
8. nil interfeys va nil ko'rsatkichni saqlovchi interfeys farqini ko'rsating: var p *MyErr = nil; var err error = p; err != nil nega true ekanini tushuntiring.
Misol: var p *MyErr = nil; var err error = p → err != nil → true; var err2 error = nil → err2 != nil → false
9. any qiymatlardan iborat ichma-ich tuzilmani (JSON'dan o'qilgan map[string]any va []any) rekursiv aylanib chiqib, barcha sonli qiymatlar yig'indisini toping.
Misol: {"a": 1, "b": [2, "x", {"c": 3.5}]} → 6.5
Standart kutubxona interfeyslari
10. io.Reader ni amalga oshiruvchi RepeatReader turini yozing: berilgan satrni N marta qaytaradi. Uni io.ReadAll bilan sinab ko'ring.
Misol: RepeatReader("ab", 3) → io.ReadAll → "ababab"
11. io.Writer ni amalga oshiruvchi CountingWriter yozing: yozilgan baytlar sonini sanaydi va ma'lumotni boshqa Writer ga uzatadi.
Misol: CountingWriter ga "salom" yozilsa → 5 bayt; keyin "Go" yozilsa → jami 7
12. io.Reader ni o'rab oluvchi UpperReader yozing: o'qilgan barcha lotin harflarini katta harfga aylantiradi. Uni strings.NewReader va os.Stdin bilan ishlating.
Misol: UpperReader("salom, dunyo") → "SALOM, DUNYO"
13. sort.Interface ni amalga oshirib, talabalarni avval guruh, so'ng baho (kamayish) va ism bo'yicha saralang.
Misol: (Ali, G1, 85), (Vali, G1, 90), (Sevara, G2, 92) → Vali, Ali, Sevara
14. error interfeysini amalga oshiruvchi ValidationError{Field, Msg} turini yarating va funksiyadan qaytaring.
Misol: ValidationError{"yosh", "manfiy bo'lmasligi kerak"} → yosh: manfiy bo'lmasligi kerak
15. flag.Value interfeysini (String, Set) amalga oshiruvchi ListFlag turini yozing: -tag go -tag web kabi takrorlanuvchi bayroqlar slice'ga yig'ilsin.
Misol: -tag go -tag web → [go web]
Interfeyslarni loyihalash
16. Kichik interfeyslar kombinatsiyasi: Reader, Writer va ularni birlashtiruvchi ReadWriter interfeyslarini e'lon qiling hamda ikkalasini ham amalga oshiruvchi Buffer turini yozing.
Misol: Write("salom"), so'ng Read → "salom"
17. Notifier interfeysi (Notify(msg string) error) ni EmailNotifier, SMSNotifier va sinov uchun FakeNotifier bilan amalga oshiring. OrderService ga bog'liqlik sifatida interfeysni uzating (dependency injection).
Misol: FakeNotifier bilan OrderService.Place(1) → xabarlar ro'yxati ["buyurtma #1 qabul qilindi"]
18. Storage interfeysi (Get, Set, Delete) uchun ikki xil amalga oshirish yozing: xotirada (map) va faylda. Dastur qaysi biridan foydalanishini konfiguratsiya orqali tanlang.
Misol: Set("a", "1"), Get("a") → 1; Delete("a"), Get("a") → «topilmadi» (xotira va fayl uchun bir xil)
19. «Strategiya» naqshi: turli chegirma strategiyalari (NoDiscount, PercentDiscount, FixedDiscount) ni DiscountStrategy interfeysi orqali amalga oshiring.
Misol: narx 100000: NoDiscount → 100000; PercentDiscount{10} → 90000; FixedDiscount{15000} → 85000
20. Funksiya turini interfeysga moslash: type HandlerFunc func(string) string turiga Handle metodini qo'shib, u Handler interfeysini qanoatlantirishini ko'rsating (http.HandlerFunc kabi).
Misol: HandlerFunc(strings.ToUpper).Handle("salom") → SALOM
Amaliy masalalar
21. Arifmetik ifoda daraxti: Expr interfeysi (Eval() float64, String() string) va Num, Add, Mul, Div turlari. (2 + 3) * 4 ifodasini quring, hisoblang va chiqaring.
Misol: (2 + 3) * 4 → (2 + 3) * 4 = 20
22. Animal interfeysi va bir nechta hayvon turlari; har biri o'z ovozini chiqaradi. type switch yordamida faqat «uy hayvonlari» uchun qo'shimcha amal bajaring.
Misol: Dog → Vov, Cat → Miyov, Cow → Mu; uy hayvonlari (Dog, Cat) uchun qo'shimcha amal bajariladi, Cow uchun yo'q
23. Plagin tizimi: Command interfeysi (Name(), Run(args []string) error) va buyruqlarni nomi bo'yicha ro'yxatdan o'tkazuvchi Registry. Foydalanuvchi kiritgan buyruqni topib bajaring.
Misol: echo salom dunyo → salom dunyo; foo → «noma'lum buyruq: foo»
24. Oddiy «middleware» zanjiri: Handler interfeysini o'rab oluvchi Logging, Timing va Recover qatlamlarini yozing va ularni zanjir qilib ulang.
Misol: Logging(Timing(Recover(h))), so'rov "salom" → [log] so'rov: salom, [timing] 120µs, javob; h panic bersa → Recover uni ushlaydi
25. Interfeys qiymatlarini solishtirish: bir xil dinamik tur va qiymatga ega interfeyslar == bilan teng ekanini, solishtirib bo'lmaydigan dinamik tur (masalan slice) bo'lganda panic yuz berishini ko'rsating.
Misol: any(1) == any(1) → true; any(1) == any("1") → false; any([]int{1}) == any([]int{1}) → panic: runtime error: comparing uncomparable type []int