Pourquoi Go n'a pas de paramètres par défaut (et c'est une bonne chose)
Imaginez : vous codez en Go et souhaitez créer une méthode avec un paramètre facultatif. Comme en Python : def greet(name="Invité"). Vous vous mettez au clavier, vous écrivez :
func (u *User) Greet(message string = "Bonjour") string { return message + ", " + u.Name}Et là, Go génère une erreur. Le compilateur rougit, mais ne laisse pas passer. Familier ? Cette question (l'originale sur Stack Overflow a des milliers de vues) tourmente un débutant sur deux en Go. Les développeurs du langage ont délibérément renoncé aux valeurs par défaut. Pourquoi ? Parce que Go est un langage d'explicite. La lisibilité du code prime sur la concision. Mais cela ne signifie pas que vous ne pouvez pas simuler une valeur par défaut en Go. Il existe au moins 5 façons élégantes de le faire. Analysons chacune.
Méthode 1 : Surcharge via différentes fonctions (façon Go)
L'approche la plus simple et la plus « Go-ique » est de créer deux fonctions. Une avec paramètre, l'autre sans.
type Config struct { Timeout int}
func NewDefaultConfig() *Config { return &Config{Timeout: 30} // valeur par défaut}
func NewConfig(timeout int) *Config { if timeout <= 0 { timeout = 30 // protection contre les erreurs } return &Config{Timeout: timeout}}Avantages : Extrêmement clair, se lit en une seconde.
Inconvénients : Avec 3-4 paramètres, on obtient une explosion de fonctions.
Méthode 2 : Structure avec constructeur (Builder Pattern)
Lorsqu'il y a beaucoup de paramètres (3+), le pattern Builder vient à la rescousse. C'est un idiome standard en Go pour gérer les paramètres optionnels.
type Server struct { Host string Port int Timeout time.Duration MaxConn int}
// Valeurs par défautfunc NewServer() *Server { return &Server{ Host: "localhost", Port: 8080, Timeout: 30 * time.Second, MaxConn: 100, }}
// Méthodes setter retournant l'objet lui-mêmefunc (s *Server) WithHost(host string) *Server { s.Host = host return s}
func (s *Server) WithPort(port int) *Server { s.Port = port return s}
// Utilisationserver := NewServer(). WithPort(9090). WithTimeout(10 * time.Second)Ce pattern est activement utilisé dans la bibliothèque standard de Go (par exemple, http.Server). Il résout le problème des paramètres par défaut en Go sans astuces.
Méthode 3 : Paramètres variadiques (astuce inattendue)
On peut utiliser les paramètres variadiques (symbole ...). C'est une technique peu évidente mais fonctionnelle pour un paramètre optionnel.
func Greet(name string, opts ...string) string { greeting := "Bonjour" // valeur par défaut if len(opts) > 0 { greeting = opts[0] } return greeting + ", " + name}
// Utilisationfmt.Println(Greet("Ivan")) // "Bonjour, Ivan"fmt.Println(Greet("Marie", "Salut")) // "Salut, Marie"Ça fonctionne, mais ça ressemble à un bricolage. Utilisez-le uniquement si vous avez besoin d'une solution rapide.
Méthode 4 : Options fonctionnelles (la plus Go-ique)
C'est la technique phare des développeurs Go. Popularisée pour la première fois par Dave Cheney. Elle permet de définir une valeur par défaut en Go pour un nombre quelconque de paramètres.
type Option func(*Client)
type Client struct { URL string Timeout time.Duration Retries int}
// Valeurs par défautfunc defaultClient() *Client { return &Client{ URL: "https://api.example.com", Timeout: 10 * time.Second, Retries: 3, }}
// Optionsfunc WithURL(url string) Option { return func(c *Client) { c.URL = url }}
func WithTimeout(t time.Duration) Option { return func(c *Client) {