3
votes

Étendre la carte à partir d'autres packages au moment de la compilation

J'essaye d'étendre une carte à travers les paquets au «moment de la compilation». Est-ce possible?

J'ai le package A avec une carte prédéfinie:

package B

import "A"

A.MyMap.Slice1["key3"] = "value" // extend the map during compile time

Et je voudrais étendre la carte pendant la compilation ». Cela doit être fait dans un autre package. Par exemple. comme ça (code ofc ne fonctionne pas.):

package A

var MyMap = map[string]string{"key1": "value", "key2": "value"}

Est-ce possible d'une manière ou d'une autre?


0 commentaires

3 Réponses :


4
votes

Vous ne pouvez pas faire cela "à la compilation". En fait, le littéral composite utilisé par package A , qui sera également construit et utilisé à l'exécution. Il n'y a pas de constantes littérales composites.

Pour aller plus loin, quel que soit le code que vous écrivez dans le package B , s'il importe le package A , le code du package B ne fonctionnera qu'après le package Un a été initialisé, y compris la carte que vous avez publiée.

Si vous voulez que A.MyMap ait une valeur différente avant de pouvoir être vu par tout autre paquet, vous devez modifier la source du paquet A . Il peut s'agir d'un fichier supplémentaire généré, qui pourrait utiliser une fonction de package init () , attribuer une nouvelle valeur à MyMap ou y ajouter de nouvelles valeurs.

Si vous le pouvez, vous pouvez également modifier le package A afin que l'initialisation de MyMap soit déplacée vers un autre fichier source, qui peut être généré.


2 commentaires

Cela signifie que la carte du package A sera construite lors de la première interaction avec le package? Ou à l'importation?


Le package A sera initialisé avant que tout autre package puisse y faire référence.



2
votes

Il s'agit en fait d'une extension au moment de l'exécution, mais elle devrait correspondre à votre exemple.

Utilisez init fonction.

package B

import "A"

func init() {
    A.MyMap["key3"] = "value"
}


1 commentaires

Celui-là fonctionne ofc. J'en ai intentionnellement besoin au moment de la compilation: - / J'ai essayé init () mais je n'ai pas réussi à appeler celui-ci sans que le paquet soit réellement importé. Je suppose que je vais devoir trouver un moyen de contourner cela d'une manière ou d'une autre.



2
votes

Vous passez une chaîne au moment de la liaison avec la commande

go build -ldflags '-X somemap={"k":"v"}'

, puis vous l'analysez pour mapper au moment de l'exécution. Vous pouvez facilement utiliser le format JSON.

En savoir plus sur GcToolchainTricks .


0 commentaires