CodeBlanks Logo Icon CodeBlanks

Metod zincirleme

Metod zincirleme için receiver döndürmeyi öğrenirsin.

Metod zincirleme

Metod alıcıyı (işaretçi olarak) döndürürse çağrılar art arda yazılabilir; buna akıcı (fluent) API denir:

type Sorgu struct{ parcalar []string }

func (s *Sorgu) Sec(a string) *Sorgu   { s.parcalar = append(s.parcalar, "SELECT "+a); return s }
func (s *Sorgu) Tablo(t string) *Sorgu { s.parcalar = append(s.parcalar, "FROM "+t); return s }
func (s *Sorgu) String() string       { return strings.Join(s.parcalar, " ") }

q := (&Sorgu{}).Sec("ad").Tablo("urunler")
fmt.Println(q)  // SELECT ad FROM urunler

Hata ile zincirleme

Go'da zincirleme yaygın değildir çünkü zincirin ortasında hata döndürmek zordur. Bir çözüm, hatayı nesnenin içinde saklayıp sonunda kontrol etmektir:

type Builder struct {
    err error
    // ...
}

func (b *Builder) Adim(x int) *Builder {
    if b.err != nil {
        return b  // önceki hata varsa atla
    }
    if x < 0 {
        b.err = errors.New("negatif değer")
    }
    return b
}

bufio.Scanner'ın Err() yöntemi de benzer bir fikri kullanır.

Uygulama Sorgu kurucu

Yukarıdaki Sorgu türünü Sec, Tablo ve String metodlarıyla yaz; ek olarak Limit(n int) *Sorgu ekle. (&Sorgu{}).Sec("ad").Tablo("urunler").Limit(5) sonucunu yazdır.

Başlangıç kodu

main.go
package main

import (
    "fmt"
    "strings"
)

func main() {
    // buraya yaz
}

Örnek çözüm

main.go
package main

import (
    "fmt"
    "strings"
)

type Sorgu struct{ parcalar []string }

func (s *Sorgu) Sec(a string) *Sorgu {
    s.parcalar = append(s.parcalar, "SELECT "+a)
    return s
}

func (s *Sorgu) Tablo(t string) *Sorgu {
    s.parcalar = append(s.parcalar, "FROM "+t)
    return s
}

func (s *Sorgu) Limit(n int) *Sorgu {
    s.parcalar = append(s.parcalar, fmt.Sprintf("LIMIT %d", n))
    return s
}

func (s *Sorgu) String() string { return strings.Join(s.parcalar, " ") }

func main() {
    fmt.Println((&Sorgu{}).Sec("ad").Tablo("urunler").Limit(5))
}

Beklenen çıktı

SELECT ad FROM urunler LIMIT 5

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Zincirlenebilir bir metodun dönüş türü ne olmalıdır?

  • Hiçbir şey
  • Kendi türünün işaretçisi (*Sorgu) Doğru cevap
  • error
  • string

Açıklama: Her çağrı aynı nesneyi döndürdüğü için bir sonraki metod onun üzerinde çalışır.

2 Alıcıyı döndür

Soru
func (s *Sorgu) Limit(n int) *Sorgu {
    s.parcalar = append(s.parcalar, fmt.Sprintf("LIMIT %d", n))
    return ____
}
Cevap
func (s *Sorgu) Limit(n int) *Sorgu {
    s.parcalar = append(s.parcalar, fmt.Sprintf("LIMIT %d", n))
    return s
}

Açıklama: return s aynı işaretçiyi döndürür; zincir sürdürülebilir.

3 Parça ve görev

Kavram Anlamı
*Sorgu dönüşü Zinciri sürdürür
String() Sonucu metne çevirir
b.err Zincirde hata saklar
(&Sorgu{}) Başlangıç nesnesi

Başlangıç bölümündeki tüm dersler