Ana içeriğe geç
Modül 5 · Ders 5 ders 5Kurstaki 25/50~10 min
Modül dersleri (5/5)

'Yeni...' yapıcı modeli

Go'da constructor anahtar kelime yok. Kongre bir fabrikadır Düzgün şekilde başlatılan bir değer veya işaretçiyi döndüren işlev. Tarafından adı genellikle NewT (veya NewXxx) olarak adlandırılır.

Temel desen: YeniT

Go
type User struct {
    Name string
    Age  int
}

func NewUser(name string, age int) *User {
    return &User{Name: name, Age: age}
}

u := NewUser("Ada", 36)
fmt.Println(u.Name)

Doğrudan değişmez &User{...}'ye göre avantajları:

  • Doğrulamayı ve varsayılanları merkezileştirirsiniz.
  • Dışa aktarılmamış alanlara sahip olabilir ve bunları yalnızca yapıcıdan doldurabilirsiniz.
  • Arayanları bozmadan uygulamayı değiştirebilirsiniz.

Doğrulamalı yapıcı: (*T, hata)

Başlatma başarısız olduğunda (*T, error) değerini döndürün:

Go
import "errors"

func NewUser(name string, age int) (*User, error) {
    if name == "" {
        return nil, errors.New("nome obbligatorio")
    }
    if age < 0 {
        return nil, errors.New("eta non valida")
    }
    return &User{Name: name, Age: age}, nil
}

u, err := NewUser("Ada", 36)
if err != nil {
    // handle...
}

Bu, herhangi bir kurucu için kullanılan deyimsel kalıptır. ön koşullar: veritabanı bağlantısı, dosya tanıtıcısı, sunucu yapılandırması vb.

Çoklu kurucular

Oluşturmak için birden fazla "yolunuz" varsa açıklayıcı adlar kullanın:

Go
func NewUser(name string) *User { ... }
func NewUserFromJSON(data []byte) (*User, error) { ... }
func NewAdmin() *User { ... }

Go'da aşırı yükleme yok: isim belirsizliği ortadan kaldırıyor.

İşlevsel seçenekler (gelişmiş bakış)

Çok sayıda isteğe bağlı parametre olduğunda, deyimsel kalıp "işlevsel seçenekler":

Go
type Option func(*Server)

func WithPort(p int) Option {
    return func(s *Server) { s.Port = p }
}

func WithTLS(cert, key string) Option {
    return func(s *Server) { s.Cert, s.Key = cert, key }
}

func NewServer(opts ...Option) *Server {
    s := &Server{Port: 8080} // default
    for _, opt := range opts {
        opt(s)
    }
    return s
}

s := NewServer(WithPort(9000), WithTLS("c.pem", "k.pem"))

Kelimenin tam anlamıyla daha ayrıntılıdır ancak isteğe bağlı birçok seçenekle iyi ölçeklenir parametrelerini korur ve geriye dönük uyumluluğu korur (yeni bir Option ekleyerek) mevcut arayanları bozmaz).

Bir kurucuya ihtiyacınız OLMADIĞINDA

Türün sıfır değeri zaten kullanışlıysa arayanın doğrudan gerçek anlamda. Kanonik örnek: sync.Mutex'nin yapıcısı yoktur, var m sync.Mutex zaten kullanıma hazır bir mutekstir. bytes.Buffer için de aynısı.

Kural şudur: "Sıfır değerini kullanışlı hale getirin". Eğer yapabilirsen hayır zorunlu yapıcı.

Deneyin

Egzersiz#go.m5.l5.e1
Denemeler: 0Yükleniyor…

Fabrika işlevini yazın NewUser(name string, age int) *&User{Name: name, Age: age} değerini döndüren kullanıcı.

Düzenleyici yükleniyor…
İpucu göster

Bir işaretçi döndürmek için gerçek `&Kullanıcı{...}` ifadesini kullanın.

3 denemeden sonra çözüm mevcut

Egzersiz#go.m5.l5.e2
Denemeler: 0Yükleniyor…

NewUser'ı (name string)'e (*Kullanıcı, hata) çevirin: if name == '' return nil, error.New('nome obbligatorio').

Düzenleyici yükleniyor…
İpucu göster

Ön koşullar varsa, (*T, hata) değerini döndürün ve başarısızlık durumunda nil + error değerini döndürün.

3 denemeden sonra çözüm mevcut

Quiz#go.m5.l5.e3
Hazır

Go'da yapıcılara yönelik deyimsel gelenek nedir?

Go
// Which signature is more idiomatic?
Cevap seçenekleri

Özet

  • Hayır constructor: bir NewT işlevi (veya aynı adlı paket içinde New) kullanın.
  • Basit durum için *T değerini döndürün; (*T, error) ön koşullar veya doğrulama ile.
  • Hata durumunda: işaretçi olarak nil değerini ve ikinci değer olarak açıklayıcı hatayı döndürün.
  • Aşırı yükleme yok; açıklayıcı adlar kullanın (NewUserFromJSON, NewAdmin).
  • "Sıfır değerini kullanışlı hale getirin": eğer yapabiliyorsanız, yapıcı gereksizdir.
  • Birçok isteğe bağlı parametre için gelişmiş model: işlevsel seçenekler.