Maison > Article > développement back-end > Les constantes de Go : au-delà des bases
Quand je suis arrivé à Go, je pensais que les constantes étaient simples et limitées : juste des valeurs fixes, rien d'extraordinaire. Mais en approfondissant, je trouve qu’ils sont assez polyvalents. Oui, ce sont des valeurs fixes, mais Go les gère de manière à la fois flexible et efficace. C'est plutôt cool. Voyons ce que cela signifie avec quelques exemples pratiques.
Dans Go, les constantes ne sont souvent pas typées jusqu'à ce que vous les utilisiez réellement. Ils ont un type par défaut mais peuvent être affectés à des variables de différents types, à condition que la valeur soit adaptée. Cela les rend adaptables d'une manière inhabituelle pour un langage typé statiquement.
Voici à quoi cela ressemble :
const x = 10 var i int = x var f float64 = x var b byte = x
Bit analogue au paradoxe de Schrödinger, x peut être un int, un float64 ou même un octet jusqu'à ce que vous l'attribuiez. Cette flexibilité temporaire permet à x de fonctionner sans problème avec différents types de votre code. Pas besoin de casting, ce qui permet de garder les choses soignées.
Vous pouvez même mélanger des constantes de différents types dans l'expression et Go déterminera le meilleur type pour le résultat :
const a = 1.5 const b = 2 const result = a * b // result is float64
Puisque a est un nombre à virgule flottante, Go promeut l'expression entière en float64. Vous n'avez donc pas à craindre de perdre en précision : Go s'en charge. Mais attention : si vous essayez d'attribuer un résultat à un int, vous obtiendrez une erreur. Go n'autorise pas les conversions implicites susceptibles de perdre des données.
Limitations
Cette flexibilité ne va que loin. Une fois que vous attribuez une constante à une variable, le type de cette variable est défini :
const y = 10 var z int = y // z is an int var k float64 = y // y can still be used as float64
Mais si vous essayez ceci :
const y = 10.5 var m int = y // Error: constant 10.5 truncated to integer
Go générera une erreur car il ne convertira pas automatiquement une constante à virgule flottante en un entier sans conversion explicite. Ainsi, même si les constantes sont flexibles, elles ne changeront pas de type pour s'adapter à des variables incompatibles.
Comprendre les valeurs par défaut des types
Lorsque vous utilisez des constantes non typées sans spécifier de type, elles supposent un type par défaut :
Constantes entières non typées par défaut int.
Constantes à virgule flottante non typées par défaut float64.
Constantes runiques non typées par défaut sur rune (qui est int32).
Constantes complexes non typées par défaut complex128.
Constantes de chaîne non typées par défaut sur chaîne.
Constantes booléennes non typées par défaut bool.
Voici un tableau rapide :
Constant Kind | Can Adapt To |
---|---|
Untyped Integer | int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr, float32, float64, complex64, complex128 |
Untyped Float | float32, float64, complex64, complex128 |
Untyped Complex | complex64, complex128 |
Untyped Rune | rune, int32, any integer type that can hold the value |
Untyped String | string |
Untyped Boolean | bool |
Go n'évalue pas seulement les constantes au moment de la compilation, il optimise également les expressions constantes. Cela signifie que vous pouvez utiliser des constantes dans les calculs, et Go calculera le résultat lors de la compilation :
const x = 10 var i int = x var f float64 = x var b byte = x
Donc, c n'est pas recalculé au moment de l'exécution ; Go a déjà compris qu'il s'agissait de 520 au moment de la compilation. Cela peut améliorer les performances, en particulier dans le code où la vitesse est importante. En utilisant des constantes, Go gère les calculs une seule fois, au lieu de les faire à chaque exécution de votre programme.
Go n'a pas de préprocesseur comme certains autres langages, mais vous pouvez utiliser des constantes dans les instructions if pour inclure ou exclure du code au moment de la compilation.
const a = 1.5 const b = 2 const result = a * b // result is float64
Lorsque le débogage est faux, le compilateur sait que la condition if ne sera jamais vraie et peut omettre le code à l'intérieur du bloc. Cela peut réduire la taille de votre binaire final. Plutôt pratique, non ?
Une fonctionnalité puissante des constantes de Go est qu'elles prennent en charge de très grands nombres. Les constantes numériques non typées dans Go ont une précision « infinie », limitée uniquement par la mémoire et le compilateur.
const y = 10 var z int = y // z is an int var k float64 = y // y can still be used as float64
Même si bigNum est bien plus grand que n'importe quel type numérique intégré comme float64 ou int, Go vous permet de le définir comme une constante. Vous pouvez faire des calculs avec ces grands nombres au moment de la compilation :
const y = 10.5 var m int = y // Error: constant 10.5 truncated to integer
Si vous utilisez Go, vous avez probablement vu iota pour créer des constantes énumérées. C'est utile car il attribue automatiquement des valeurs incrémentielles.
Vous pouvez également utiliser des expressions dans des déclarations de constantes avec iota pour créer des constantes associées.
const a = 100 const b = 5 const c = a * b + 20 // c is computed at compile time
Ce code définit des constantes pour le kilo-octet, le mégaoctet, le gigaoctet et le téraoctet en utilisant le décalage de bits. Il est calculé au moment de la compilation. C'est une façon intéressante de générer une série de constantes liées.
Je trouve iota vraiment utile pour ce genre de choses. Comme Go n'a pas de type d'énumération intégré, vous pouvez simuler efficacement des énumérations à l'aide de l'identifiant iota et des types personnalisés.
Les constantes peuvent utiliser des opérations et des décalages au niveau du bit, aboutissant même à des valeurs plus grandes que n'importe quel type intégré.
const debug = false func main() { if debug { fmt.Println("Debugging enabled") } // The above block might be removed by the compiler if debug is false }
Ici, shiftedValue devient un très grand nombre en raison du grand montant de décalage. Cette valeur est trop grande pour les types entiers standard mais est valable comme constante jusqu'à ce que vous essayiez de l'attribuer :
const bigNum = 1e1000 // This is a valid constant
Cela montre que les constantes peuvent représenter des valeurs que vous ne pouvez pas stocker dans des variables, ce qui permet des calculs au moment de la compilation avec de très grands nombres.
Bien que les constantes de Go soient flexibles, il y a certaines choses qu'elles ne peuvent pas faire.
Les constantes ne peuvent pas être référencées par des pointeurs
Les constantes n'ont pas d'adresse mémoire au moment de l'exécution. Vous ne pouvez donc pas prendre l'adresse d'une constante ou utiliser un pointeur vers celle-ci.
const x = 10 var i int = x var f float64 = x var b byte = x
Constantes avec des pointeurs typés nuls
Bien que nil puisse être attribué à des variables de type pointeur, tranche, carte, canal et fonction, vous ne pouvez pas créer une constante contenant un pointeur nul tapé.
const a = 1.5 const b = 2 const result = a * b // result is float64
Cela ajoute à l'immuabilité et à la nature des constantes au moment de la compilation dans Go.
Appels de fonction dans les déclarations constantes
Seules certaines fonctions intégrées peuvent être utilisées dans des expressions constantes, comme len, cap, real, imag et complexe.
const y = 10 var z int = y // z is an int var k float64 = y // y can still be used as float64
En effet, ces fonctions intégrées peuvent être utilisées
Types et constantes composites
Les constantes ne peuvent pas représenter directement des types composites tels que des tranches, des cartes ou des structures. Mais vous pouvez utiliser des constantes pour les initialiser.
const y = 10.5 var m int = y // Error: constant 10.5 truncated to integer
Le code ci-dessus ne fonctionne pas car vous ne pouvez pas déclarer une tranche comme constante. Cependant, vous pouvez utiliser des constantes à l'intérieur d'une tranche variable :
const a = 100 const b = 5 const c = a * b + 20 // c is computed at compile time
N'oubliez pas que les types comme slice lui-même ne sont pas une constante : vous ne pouvez pas le déclarer comme tel. Cependant, les éléments à l'intérieur peuvent être des constantes.
Conversion explicite en cas de besoin
Si une constante non typée ne peut pas être directement affectée en raison d'une incompatibilité de type ou d'une éventuelle perte de précision, vous devez utiliser une conversion de type explicite.
const debug = false func main() { if debug { fmt.Println("Debugging enabled") } // The above block might be removed by the compiler if debug is false }
J'espère que cela vous donne une meilleure idée de Constant. Ce ne sont pas seulement de simples valeurs fixes ; mais aussi une fonctionnalité flexible qui peut rendre votre code plus expressif et efficace.
Je suis encore relativement nouveau dans le partage de mes expériences dans Go et j'ai hâte d'apprendre et de m'améliorer. Si vous avez trouvé cet article utile ou si vous avez des suggestions sur la façon dont je peux l'améliorer, veuillez le publier dans les commentaires.
Mon tout premier article Reddit sur « Prise en charge UTF-8 de Go : une limitation intéressante » (ne nécessite pas de connexion) qui a suscité toute une attention.
Dans l'attente de vos commentaires.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!