La fonction new()
Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy — leçon 22 sur 107.
Go fournit une fonction intégrée appelée new() qui alloue de la mémoire pour un type et retourne un pointeur vers celui-ci. La mémoire allouée est initialisée à la valeur zéro du type.
p := new(int) // alloue de la mémoire pour un int
fmt.Println(*p) // 0 (valeur par défaut)
fmt.Println(p) // 0xc000018030 (adresse mémoire)La fonction new() prend un type comme argument et retourne un pointeur vers une valeur zéro nouvellement allouée de ce type. Ceci est particulièrement utile lorsque vous avez besoin d'un pointeur mais que vous n'avez pas de variable existante à référencer.
Avec les structures, new() crée un pointeur vers une structure dont tous les champs sont initialisés à leur valeur zéro.
type Person struct {
Name string
Age int
}
p := new(Person)
fmt.Println(p.Name) // "" (chaîne vide)
fmt.Println(p.Age) // 0Vous pourriez vous demander quand utiliser new() par rapport à l'opérateur d'adresse &. Les deux approches ci-dessous sont équivalentes :
// Utilisation de new()
p1 := new(Person)
// Utilisation de l'opérateur d'adresse avec un littéral
p2 := &Person{}La syntaxe &Person{} est plus courante en pratique car elle vous permet d'initialiser les champs en même temps. Utilisez new() lorsque vous voulez spécifiquement une instance avec des valeurs par défaut (zero-valued) et que vous préférez une sémantique d'allocation de mémoire explicite.
Défi
FacileConstruisons un gestionnaire de configuration qui démontre comment new() alloue de la mémoire et initialise les structs à leurs valeurs par défaut (zero values). Vous verrez comment cette approche diffère de l'utilisation de l'opérateur d'adresse avec un littéral de struct.
Vous organiserez votre code sur deux fichiers :
config.go: Définissez une structServerConfigavec les champsHost(string),Port(int),MaxConnections(int) etDebugMode(bool). Créez deux fonctions :NewServerConfigqui utilisenew()pour allouer unServerConfiget retourne directement le pointeur (avec toutes les valeurs par défaut).ConfigureServerqui prend un pointeur*ServerConfigainsi qu'une chaîne host et un entier port, puis définit ces champs sur la configuration via le pointeur.
Displaysur*ServerConfigqui retourne une chaîne formatée affichant toutes les valeurs de configuration.main.go: Lisez un hôte et un port depuis l'entrée. Tout d'abord, créez une configuration en utilisantNewServerConfig()et affichez-la pour montrer les valeurs par défaut. Ensuite, utilisezConfigureServerpour définir l'hôte et le port, et affichez à nouveau la configuration pour montrer les valeurs mises à jour.
Les entrées suivantes seront fournies :
- Ligne 1 : Nom de l'hôte (string)
- Ligne 2 : Numéro de port (integer)
Votre méthode Display doit retourner une chaîne dans ce format exact :
Host: [Host]
Port: [Port]
MaxConnections: [MaxConnections]
DebugMode: [DebugMode]Affichez la sortie de display deux fois — une fois avant la configuration (montrant les valeurs par défaut) et une fois après la configuration (montrant l'hôte et le port mis à jour).
Par exemple, avec localhost et 8080, votre sortie devrait être :
Host:
Port: 0
MaxConnections: 0
DebugMode: false
Host: localhost
Port: 8080
MaxConnections: 0
DebugMode: falseRemarquez comment le premier affichage montre toutes les valeurs par défaut (chaîne vide, 0, 0, false) parce que new() initialise tout aux valeurs par défaut. Après l'appel à ConfigureServer, seuls l'hôte et le port changent tandis que les autres champs restent à leurs valeurs par défaut.
Aide-mémoire
La fonction new() alloue de la mémoire pour un type et renvoie un pointeur vers celui-ci, initialisé à la valeur zéro du type :
p := new(int) // alloue de la mémoire pour un int
fmt.Println(*p) // 0 (valeur zéro)
fmt.Println(p) // 0xc000018030 (adresse mémoire)Avec les structs, new() crée un pointeur vers une struct dont tous les champs sont définis sur leurs valeurs zéro :
type Person struct {
Name string
Age int
}
p := new(Person)
fmt.Println(p.Name) // "" (chaîne vide)
fmt.Println(p.Age) // 0Utiliser new() par rapport à l'opérateur d'adresse & - les deux sont équivalents :
// Utilisation de new()
p1 := new(Person)
// Utilisation de l'opérateur d'adresse avec un littéral
p2 := &Person{}La syntaxe &Person{} est plus courante car elle permet l'initialisation des champs au moment de la création. Utilisez new() lorsque vous voulez une instance à valeur zéro avec une sémantique d'allocation de mémoire explicite.
Essayez vous-même
package main
import (
"fmt"
)
func main() {
// Lire l'entrée
var host string
var port int
fmt.Scanln(&host)
fmt.Scanln(&port)
// TODO: Créer une configuration en utilisant NewServerConfig() et l'afficher
// Cela montrera les valeurs par défaut (zero values)
// TODO: Utiliser ConfigureServer pour définir l'hôte et le port
// TODO: Afficher à nouveau la configuration pour montrer les valeurs mises à jour
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO en Go
Fichiers externesEspace de travail et Modules GoPackages et ImportsNoms exportés vs non exportésIntroduction à la POO en GoLes Structs comme ClassesDéfinir des méthodes sur les StructsReceveurs par pointeur vs par valeurInitialisation de StructsFonctions constructeursRécapitulatif - Calculatrice simple4Interfaces
Introduction aux interfacesImplémentation impliciteL'interface comme contratInterface vide (any)Assertion de typeType SwitchComposition d'interfacesInterfaces Stringer & ErrorRécapitulatif - Calculateur de formes7Encapsulation
Champs exportés vs non exportésEncapsulation au niveau du packageMéthodes Getter & SetterMasquage d'informations en GoRécapitulatif - Dossiers étudiants10Génériques (Go 1.18+)
Introduction aux génériquesParamètres de typeContraintes de typeStructures génériquesContournement pour les méthodes génériquesRécapitulatif - Collections génériques13Patrons de conception, Partie 1
Introduction aux Design PatternsPatron SingletonPatron FactoryPatron Abstract FactoryPatron ObserverPatron Strategy2Exploration approfondie des Types et Structs
Types de base et compositesDéfinitions de types personnalisésTags de StructStructs anonymesStructs imbriquéesValeurs par défaut et Zero ValuesRécapitulatif - Carnet de contacts5Composition plutôt qu'héritage
Pourquoi Go n'a pas d'héritageLes bases de l'imbrication de structsPromotion de méthodesImbriquer plusieurs structsImbrication vs AgrégationMasquage de méthodes imbriquéesRécapitulatif - Hiérarchie des employés8Gestion des erreurs & POO
L'interface errorTypes d'erreurs personnalisésError Wrapping (fmt.Errorf)Erreurs sentinelleserrors.Is() et errors.As()Panic, Defer et RecoverRécapitulatif - File Parser11Bibliothèque standard et POO
io.Reader & io.WriterL'interface sort.InterfaceL'interface fmt.Stringerencoding/json avec les StructsL'interface http.HandlerRécapitulatif - Modèles d'API REST14Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositeMiddleware en tant que Décorateur3Pointeurs et Mémoire
Bases des pointeurs en GoPointeurs vers des structsPassage par valeur vs référenceLa fonction new()Garbage Collection en GoRécapitulatif - Constructeur de liste chaînée6Le polymorphisme en Go
Le polymorphisme via les interfacesLe Duck Typing en GoRègles de satisfaction des interfacesCollections polymorphesInjection de dépendancesRécapitulatif - Processeur de paiement9Concurrence et POO
Bases des GoroutinesChannels et CommunicationChannels avec buffer vs sans bufferL'instruction Selectsync.Mutex et sync.RWMutexsync.WaitGroupConception de structures Thread-SafeRécapitulatif - Worker Pool