constante netipizate în Go

Constantele fără tip se adaptează tipului de care e nevoie și sunt calculate cu precizie mare la compilare.

Sintaxă
const N = 10          // netipizată: se potrivește oricărui tip numeric
const M int64 = 10    // tipizată: doar int64

Ce face constante netipizate

O constantă declarată fără tip (const N = 10) sau un literal (10, 2.5, "text") este netipizată. Ea primește un tip abia când este folosită: aceeași constantă N poate fi adunată cu un int, cu un float64 sau cu un time.Duration, fără conversie. Când nu există un tip impus (de exemplu în x := N), se folosește tipul implicit: int, float64, rune, complex128, string sau bool.

Aritmetica pe constante netipizate se face la compilare, cu precizie foarte mare, deci valori intermediare uriașe (1 << 100) sunt permise, atât timp cât rezultatul final încape în tipul în care este folosit. Dacă nu încape, compilarea eșuează cu overflows.

O constantă tipizată (const Limita int64 = 100) se comportă ca o valoare de acel tip: pentru a o folosi cu alt tip ai nevoie de conversie explicită.

Exemple

Exemplul 1: Aceeași constantă cu tipuri diferite

Pauza se adaptează: devine int, float64 și time.Duration.

package main

import (
    "fmt"
    "time"
)

const Pauza = 3

func main() {
    var zile int = Pauza
    var medie float64 = Pauza / 2.0
    asteptare := Pauza * time.Second
    implicit := Pauza

    fmt.Println(zile, medie, asteptare)
    fmt.Printf("%T %T %T %T\n", zile, medie, asteptare, implicit)
}

Rezultat

3 1.5 3s
int float64 time.Duration int

Exemplul 2: Precizie mare la compilare

Mare nu încape în niciun tip întreg, dar Mare >> 98 da, deci se poate folosi.

package main

import "fmt"

const Mare = 1 << 100

func main() {
    fmt.Println(Mare >> 98) // 4
    const Treime = 1.0 / 3
    fmt.Println(Treime * 3) // calculat exact la compilare
}

Rezultat

4
1

Exemplul 3: Constantă tipizată: conversie obligatorie

package main

import "fmt"

const LimitaNetipizata = 100
const LimitaTipizata int64 = 100

func main() {
    var n int = 40
    fmt.Println(n + LimitaNetipizata)      // merge: constanta devine int
    fmt.Println(int64(n) + LimitaTipizata) // trebuie conversie
}

Rezultat

140
140

Greșeli frecvente

  • var b byte = 300: constanta nu încape, eroarea este cannot use 300 (untyped int constant) as byte value in variable declaration (overflows).
  • x := 1 << 100: tipul implicit int nu poate ține valoarea (cannot use 1 << 100 ... as int value in assignment (overflows)).
  • Crezând că n + LimitaTipizata merge cu n int: tipurile int și int64 nu se amestecă (mismatched types).

Comenzi înrudite

  • const: Declară constante: valori fixe, calculate la compilare (numere, texte, bool), care nu se mai pot modifica.
  • iota: Contor folosit în blocurile const: pornește de la 0 și crește cu 1 la fiecare rând; ideal pentru enumerări.
  • tipuri de bază: Tipurile simple din Go: bool, string, întregi cu și fără semn, numere reale, complexe, byte și rune.
  • int, int8…int64, uint, uint8…uint64, uintptr: Tipurile întregi din Go: cu semn (int, int8..int64) și fără semn (uint, uint8..uint64, uintptr), cu limitele lor.