Costanti

Le dichiarazioni di costanti sono simili alle dichiarazioni di variabili ma con la parola const al posto di var.

L'inizializzazione è obbligatoria.

Non si può riassegnare un valore ad una costante.

Esempio:

(040constants.go):

package main

import "fmt"
import "math"

// Dichiarazione di costante
const s string = "constant"

func main() {
	fmt.Println(s)

	// Può essere ovunque nel programma
	const n = 500000000

	// Può avere un valore risultato di espressione
	// Internamente registrato a massima precisione
	const d = 3e20 / n
	fmt.Println(d)

	// Non ha un tipo finchè non gli viene dato
	// per esempio con un cast
	fmt.Println(int64(d))

	// oppure dal contesto - qui è un float64
	fmt.Println(math.Sin(n))
}

Normalmente, le variabili sono mutabili:

  • Sono allocate in memoria statica (stack)
  • Si può riassegnare un valore

Alcune variabili sono immutabili (stringhe ed array):

  • Sono allocate in memoria dinamica (heap)
  • La riassegnazione causa una nuova allocazione

Una costante è immutabile.

La dichiarazione di tipo e l’assegnazione devono essere simultanee.

Una costante numerica non deve avere subito un tipo, ma allora deve subire un cast prima dell’uso.

Cast

Trasformazione di tipo:

variabile1 = tipo(variabile2)

I cast sono un cambiamento di rappresentazione interna di una variabile

  • Non tutti i cast sono possibili
  • Alcuni cast possono causare perdita di precisione

Il cast è necessario perchè il compilatore esige lo stesso tipo ai due lati di un'assegnazione.

Per esempio:

(types.go):

package main

import "fmt"

func main() {
  x := 2.5678
  y := 6.56789
  var i int
  i = y / x
  fmt.Println("i= ", i)
}

quando compilato dà l'errore:

./types.go:9:4: cannot use y / x (type float64) as type int in assignment

Occorre invece un cast:

i = int(y / x)

con conseguente perdita di precisione.

Notare che un cast ha lo stesso formato di una funzione, ma non è una funzione.

In altre parole, se vi fossero due struct (vedi oltre, sono quasi come classi) di nome arance e mele, il codice:

var f1 mele
var f2 arance
...
f1 = mele(f2)

tenta di trasformare arance in mele, e dà un errore a runtime. Le struct sono solo quasi come classi, e non esiste il concetto di ereditarietà.