Go's basic types are:
Copy bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte
rune
float32 float64
complex64 complex128
The int
, uint
, and uintptr
types are usually 32 bits wide on 32-bit systems and 64 bits wide on 64-bit systems.
When you need an integer value you should use int unless you have a specific reason to use a sized or unsigned integer type.
Copy package main
import (
"fmt"
"math/cmplx"
)
var (
ToBe bool = false
MaxInt uint64 = 1 << 64 - 1
z complex128 = cmplx . Sqrt ( - 5 + 12i )
)
func main ( ) {
fmt . Printf ( "Type: %T Value: %v\n" , ToBe , ToBe )
fmt . Printf ( "Type: %T Value: %v\n" , MaxInt , MaxInt )
fmt . Printf ( "Type: %T Value: %v\n" , z , z )
}
Variables declared without an explicit initial value are given their zero value .
This initialization is done recursively , so for instance each element of an array of structs will have its fields zeroed if no value is specified.
The zero value is:
0
for numeric types,false
for the boolean type, and""
(the empty string) for strings.nil
for pointers, functions, interfaces, slices, channels, and maps.These two simple declarations are equivalent:
After
Copy type T struct { i int ; f float64 ; next * T }
t := new ( T )
the following holds:
Copy t . i == 0
t . f == 0.0
t . next == nil
The same would also be true after
Type conversions# The expression T(v)
converts the value v
to the type T
.
Some numeric conversions:
Copy var i int = 42
var f float64 = float64 ( i )
var u uint = uint ( f )
Or, put more simply:
Copy i := 42
f := float64 ( i )
u := uint ( f )
Unlike in C, in Go assignment between items of different type requires an explicit conversion.
The most common numeric conversions are Atoi (string to int) and Itoa (int to string).
Copy i , err := strconv . Atoi ( "-42" )
s := strconv . Itoa ( - 42 )
These assume decimal and the Go int type.
ParseBool, ParseFloat, ParseInt, and ParseUint convert strings to values:
Copy b , err := strconv . ParseBool ( "true" )
f , err := strconv . ParseFloat ( "3.1415" , 64 )
i , err := strconv . ParseInt ( "-42" , 10 , 64 )
u , err := strconv . ParseUint ( "42" , 10 , 64 )
Type inference# When declaring a variable without specifying an explicit type (either by using the :=
syntax or var =
expression syntax), the variable's type is inferred from the value on the right hand side.
When the right hand side of the declaration is typed, the new variable is of that same type:
But when the right hand side contains an untyped numeric constant, the new variable may be an int
, float64
, or complex128
depending on the precision of the constant:
Copy i := 42
f := 3.142
g := 0.867 + 0.5i
Constants# Constants are declared like variables, but with the const
keyword.
Constants can be character, string, boolean, or numeric values.
Constants cannot be declared using the :=
syntax.
Copy package main
import "fmt"
const Pi = 3.14
func main ( ) {
const World = "世界"
fmt . Println ( "Hello" , World )
fmt . Println ( "Happy" , Pi , "Day" )
const Truth = true
fmt . Println ( "Go rules?" , Truth )
}
Hello 世界
Happy 3.14 Day
Go rules? true
Go's iota
identifier is used in const
declarations to simplify definitions of incrementing numbers.
Counter# Copy package main
import (
"fmt"
)
const (
a = iota
b = iota
c = iota
)
const (
r = iota
s = iota
t = iota
)
func main ( ) {
fmt . Println ( a )
fmt . Println ( b )
fmt . Println ( c )
fmt . Println ( r )
fmt . Println ( s )
fmt . Println ( t )
}
0
1
2
0
1
2
Simplified Counter# Copy package main
import (
"fmt"
)
const (
a = iota
b
c
)
func main ( ) {
fmt . Println ( a )
fmt . Println ( b )
fmt . Println ( c )
}
0
1
2
Counter from 1# Copy package main
import (
"fmt"
)
const (
_ = iota
a
b
c
)
func main ( ) {
fmt . Println ( a )
fmt . Println ( b )
fmt . Println ( c )
}
1
2
3
Counter from an offset# Copy package main
import (
"fmt"
)
const (
_ = iota + 10
a
b
c
)
func main ( ) {
fmt . Println ( a )
fmt . Println ( b )
fmt . Println ( c )
}
11
12
13
Application# File Size# Copy package main
import (
"fmt"
)
const (
_ = iota
KB = 1 << ( 10 * iota )
MB
GB
TB
)
func main ( ) {
fileSize := 2000000000.
fmt . Printf ( "%.2fGB" , fileSize / GB )
}
Permission# Copy package main
import (
"fmt"
)
const (
X = 1 << iota
W
R
)
func main ( ) {
var permission byte = X | W | R
fmt . Printf ( "%b\n" , permission )
fmt . Printf ( "Is readable? %v" , R & permission == R )
}
111
Is readable? true
Numeric Constants# Numeric constants are high-precision values.
An untyped constant takes the type needed by its context.
Copy package main
import "fmt"
const (
Big = 1 << 100
Small = Big >> 99
)
func needInt ( x int ) int { return x * 10 + 1 }
func needFloat ( x float64 ) float64 {
return x * 0.1
}
func main ( ) {
fmt . Println ( needInt ( Small ) )
fmt . Println ( needFloat ( Small ) )
fmt . Println ( needFloat ( Big ) )
}
21
0.2
1.2676506002282295e+29
Try printing needInt(Big)
.
Copy package main
import "fmt"
const (
Big = 1 << 100
Small = Big >> 99
)
func needInt ( x int ) int { return x * 10 + 1 }
func needFloat ( x float64 ) float64 {
return x * 0.1
}
func main ( ) {
fmt . Println ( needInt ( Big ) )
}
constant 1267650600228229401496703205376 overflows int
(An int
can store at maximum a 64-bit integer, and sometimes less.)
bit# Copy package main
import (
"fmt"
)
func main ( ) {
a := 10
b := 3
fmt . Println ( a & b )
fmt . Println ( a | b )
fmt . Println ( a ^ b )
fmt . Println ( a &^ b )
c := 8
fmt . Println ( c << 2 )
fmt . Println ( c >> 2 )
}
2
11
9
8
32
2
string# Copy package main
import (
"fmt"
)
func main ( ) {
s := "this is a string"
fmt . Printf ( "%v, %T" , s [ 0 ] , s [ 0 ] )
fmt . Printf ( "%v, %T" , string ( s [ 0 ] ) , s [ 0 ] )
}
116 , uint8
t , uint8
rune# Copy package main
import (
"fmt"
)
func main ( ) {
var r rune = 'a'
fmt . Printf ( "%v, %T\n" , r , r )
}
97 , int32