Every value in a program has a type, which defines two things: how much memory it takes and which operations make sense with it (adding two numbers does; adding two booleans doesn’t).
Primitives and composites
- Primitives: the basic building blocks the language ships with: integers, floating point, booleans, characters.
- Composites: built from other types: arrays, lists, maps, structs, classes.
| Go | Java | |
|---|---|---|
| Integers | int8, int16, int32, int64, int (32 or 64 bits, depending on the platform), unsigned uint variants | byte (8), short (16), int (32), long (64), all signed |
| Floating point | float32, float64 | float, double |
| Boolean | bool | boolean |
| Character | byte (= uint8), rune (= int32, a Unicode code point) | char (16 bits, UTF-16) |
| Text | string | String (a class, not a primitive) |
Static × dynamic, strong × weak
- Static (Go, Java): every variable’s type is known at compile time, and type errors don’t even compile.
- Dynamic (Python, JavaScript): the type is checked while the program runs.
- Strong: the language doesn’t convert types on its own in surprising ways (Go won’t add an
intto afloat64without an explicit conversion). - Weak: it converts implicitly (
"1" + 1in JavaScript is"11").
Watch out: silent overflow
Every integer has a limit. Go past it and the value “wraps around” without any error:
var x int32 = math.MaxInt32 // 2147483647x++fmt.Println(x) // -2147483648int x = Integer.MAX_VALUE; // 2147483647x++;System.out.println(x); // -2147483648For values that can grow (counters, money in cents), use int64/long. In Java, Math.addExact throws an exception instead of wrapping.
See also: Variables and constants, Strings and types in Go.