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
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:
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:
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":
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
Fabrika işlevini yazın NewUser(name string, age int) *&User{Name: name, Age: age} değerini döndüren kullanıcı.
İ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
NewUser'ı (name string)'e (*Kullanıcı, hata) çevirin: if name == '' return nil, error.New('nome obbligatorio').
İ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
Go'da yapıcılara yönelik deyimsel gelenek nedir?
// Which signature is more idiomatic?Özet
- Hayır
constructor: birNewTişlevi (veya aynı adlı paket içindeNew) kullanın. - Basit durum için
*Tdeğerini döndürün;(*T, error)ön koşullar veya doğrulama ile. - Hata durumunda: işaretçi olarak
nildeğ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.