Differences between Go and the “C” type languages
Variable declaration
int i; // C#
var i int = 5 // Go
i := 5 // Go
Function declaration
private int AddNumbers (int a, int b) {...} // C#
func addNumbers(a int, b int) int {...} // Go
Loops
for
for (int i = 0; i < 5; i++) {...} // C#
for i := 0; i < 5; i++ {...} // Go
while
// "while" loop in C#
int i = 0;
while (i < 5) {
i++;
}
// "while" loop in Go (the init and post statements are optional, so "for" can be used as "while")
i := 0
for i < 5 {
i++
}
infinite loop
while (true) {...} // C#
for {...} // Go
if
if (a == b ) {... } // C# if a == b {...} // Go
switch
No “break” is needed after every “case”
defer
Wait with the function call until the surrounding function completes
deferred function calls are pushed into a last-in first-out stack
Arrays
var a [5]int // Go (array with 5 integer elements)
Lists
Use “slices” with the “append” function to dynamically add elements to a slice and the underlying array.
Classes
There are no classes in Go, use “methods” that are functions with receivers (attributes). The receiver has to be specified in the same package as the function.
func (v MyStruct) MyFunction() int {...}
Use pointer receivers to modify the original reference of the receiver in the function.
func (v *MyStruct) MyFunction() int { v.X = 5 }
Functions with a receiver can take a value or pointer. It is recommended to use pointer receivers to be able to modify the passed-in argument and avoid copying it.
Private and public (exported) names
- Exported (public) names start with an upper case letter
math.Pi
- Not exported (private) names start with lower case letter
mypackage.private
Variables
- When declaring variables, the name comes first, the type comes last
var i int
- We can declare multiple variables with the same type, and specify the type only once for the last one in one statement
var a, b, c bool
- Inside functions the short variable variable declaration uses the implicit type
d := 5
- We can declare and assign values to multiple variables with one statement
e, f, g := true, false, "yes!"
- The basic types are
bool
string
int (32 bit on 32 bit systems, 64 bit on 64 bit systems)
int8 int16 int32 int64
uint (32 bit on 32 bit systems, 64 bit on 64 bit systems)
uint8 uint16 uint32 uint64
uintptr (32 bit on 32 bit systems, 64 bit on 64 bit systems)
byte // alias for uint8
rune // alias for int32
// represents a Unicode code point
float32 float64
complex64 complex128 - To print the type and value of a variable use %T and %v
a := 8
fmt.Printf("Type: %T Value: %v", a, a)
Type: int Value 8 - Explicit type conversions with a NewType(value) syntax are required for assignments between different types
var i int = 5
var f float32 = float32(i)
Functions
- If a function returns multiple values, enclose the return declaration in parentheses
func myfunc(x, y string) (string, string) {
return y, x
}
Slices
Dynamic view into an array. array[first:last+1] (the element specified by the second argument is not part of the slice)
var s []int = array[0:6]
Create a slice and the underlying array with “make([]type, length of the slice, capacity of the array)”
b := make([]int, 0, 5) // len(b)=0, cap(b)=5
To dynamically add elements to the slice and the underlying array use the “append” function
var s []int
s = append(s, 1)
// Appends an element with the value of 1 to the slice and the array
To iterate through an array or slice use the “for range” expression. It returns the index and the value of the current element
for i, v := range my_array{}
Maps
// key is string, value is integer (here we use "make" to create it)
m := make(map[string]int)
// key is string, value is a struct
type MyStruct struct {
x, y int
}
var m map[string]MyStruct