194 votes

Comment définir des valeurs par défaut dans les structs Go

Il existe plusieurs réponses/techniques à la question ci-dessous :

  1. Comment définir des valeurs par défaut pour les structs golang ?
  2. Comment initialiser les structs en golang

J'ai quelques réponses, mais une discussion plus approfondie est nécessaire.

1 votes

@icza Votre réponse fournit un moyen de le faire, mais si l'on se fie au titre de la question, elle n'est en aucun cas similaire ou consultable, car il s'agit d'une question très spécifique. Je vais cependant ajouter le lien dans ma réponse.

0 votes

Il y a deux questions ici, choisissez-en une. En supposant que vous optiez pour la première question (conformément au titre de la question), veuillez être plus précis quant à vos recherches antérieures et aux points sur lesquels vos autres réponses nécessitent une discussion plus approfondie.

122voto

vodolaz095 Points 2998

Une idée possible est d'écrire une fonction constructrice séparée

//Something is the structure we work with
type Something struct {
     Text string 
     DefaultText string 
} 
// NewSomething create new instance of Something
func NewSomething(text string) Something {
   something := Something{}
   something.Text = text
   something.DefaultText = "default text"
   return something
}

11 votes

Oui, c'est l'un des moyens que j'ai également mentionné dans ma réponse, mais il n'y a aucun moyen de forcer quiconque à utiliser cette fonction uniquement.

0 votes

@Prateek c'est soit ça, soit utiliser une interface, ce qui serait laid et trop compliqué.

45 votes

@Prateek oui, vous pouvez forcer les gens à utiliser ce constructeur si vous rendez simplement le type lui-même non exporté. Vous pouvez exporter la fonction NewSomething et même les champs Text et DefaultText mais il ne faut pas exporter le type de structure. something .

80voto

Prateek Points 1705
  1. Force une méthode pour obtenir la structure (la méthode du constructeur).

    De ce poste :

    Une bonne conception est de rendre votre type non exporté, mais de fournir une fonction de construction exportée comme NewMyType() dans lequel vous pouvez initialiser correctement votre structure/type. Retournez également un type d'interface et non un type concret, et l'interface doit contenir tout ce que les autres veulent faire avec votre valeur. Et votre type concret doit implémenter cette interface bien sûr.

    Pour ce faire, il suffit de rendre le type lui-même non exporté. Vous pouvez exporter la fonction NewSomething et même les champs Text et DefaultText, mais n'exportez pas le type struct something.

  2. Une autre façon de le personnaliser pour votre propre module est d'utiliser un fichier de type Config struct pour définir les valeurs par défaut (Option 5 dans le lien). Mais ce n'est pas une bonne solution.

7 votes

Il s'agit maintenant d'un lien brisé (404) : joneisen.tumblr.com/post/53695478114/golang-and-default-values

4 votes

Il est disponible dans le machine à remonter le temps .

1 votes

Pour information, je pense qu'il s'agit de l'"Option 3", du moins dans le lien de la machine wayback. (Il n'y a pas d'"Option 5", là).

45voto

wolfson109 Points 151

Un problème avec l'option 1 de la réponse de Victor Zamanian est que si le type n'est pas exporté, les utilisateurs de votre paquetage ne peuvent pas le déclarer comme type pour les paramètres de fonction, etc. Une façon de contourner ce problème serait d'exporter une interface à la place de la structure, par ex.

package candidate
// Exporting interface instead of struct
type Candidate interface {}
// Struct is not exported
type candidate struct {
    Name string
    Votes uint32 // Defaults to 0
}
// We are forced to call the constructor to get an instance of candidate
func New(name string) Candidate {
    return candidate{name, 0}  // enforce the default value here
}

Ce qui nous permet de déclarer les types de paramètres de fonction en utilisant l'interface Candidate exportée. Le seul inconvénient que je vois à cette solution est que toutes nos méthodes doivent être déclarées dans la définition de l'interface, mais on pourrait faire valoir que c'est de toute façon une bonne pratique.

4voto

RdB Points 136

_De https://golang.org/doc/effective_go.html#composite_literals :_

Parfois, la valeur zéro n'est pas suffisante et un constructeur d'initialisation est nécessaire, comme dans cet exemple dérivé du package os.

    func NewFile(fd int, name string) *File {
      if fd < 0 {
        return nil
      }
      f := new(File)
      f.fd = fd
      f.name = name
      f.dirinfo = nil
      f.nepipe = 0
      return f
}

-4voto

user10209901 Points 1
type Config struct {
    AWSRegion                               string `default:"us-west-2"`
}

2 votes

C'est incorrect. Au mieux, vous pourriez définir une valeur de balise sur ce champ, puis accéder à sa valeur par réflexion, mais même dans ce cas, la syntaxe est incorrecte (il manque des ticks arrière) et vous ne pourriez définir une valeur par défaut que pour un type de chaîne. Si vous avez une idée de ce à quoi cet exemple se réfère spécifiquement, veuillez ajouter un lien pour vous y référer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X