Go is divided into packages. Packages are the equivalent of modules in Python. Only the main
package can be executed with go run
.
We can import packages with import
. The Hello World application imported the fmt
package. Multiple imports are similar:
import (
"fmt"
"math/rand"
"otherimport"
)
In Go, a name is exported if it begins with a capital letter.
When importing a package, you can refer only to its exported names. Unexported names are not accessible from outside the package.
Unlike C, type comes after variable name except for pointers.
// 02.1-01-multiply.go
package main
import "fmt"
func multiply(x int, y int) int {
return x * y
}
func main() {
fmt.Println(multiply(10,20))
}
https://play.golang.org/p/jZrNpGAEWds
A function can return any number of values. Gone are the days when we had to use pointers in function parameters as extra return values.
// 02.1-02-addTwo.go
package main
import "fmt"
func addTwo(x int, y int) (int, int) {
return x+2, y+2
}
func main() {
fmt.Println(addTwo(10,20))
}
https://play.golang.org/p/sH0LeYIBpOM
If multiple variables have the same type we can declare them like this:
func addTwo(x, y int) (int, int) {
return x+2, y+2
}
https://play.golang.org/p/Dwl94tWctK8
Return values can be named. If so, they are treated as variables defined in the function.
A return statement without arguments returns the named return values. This is known as a "naked" return. Using named return values and naked return is frowned upon unless it helps readability.
// 02.1-03-addTwo2.go
package main
import "fmt"
func addTwo2(x int, y int) (xPlusTwo int, yPlusTwo int) {
xPlusTwo = x + 2
yPlusTwo = y + 2
return xPlusTwo, yPlusTwo
}
func main() {
fmt.Println(addTwo2(20,30))
}
https://play.golang.org/p/wiC9HJ0uxDN
init
function is used to set up the state. A common practice is to declare flags in it.
- Imported packages are initialized.
- Variable declarations evaluate their initializers.
init
function executes.
// 02.1-09-init.go
package main
import "fmt"
func init() {
fmt.Println("Executing init function!")
}
func main() {
fmt.Println("Executing main!")
}
https://play.golang.org/p/HfL8YjGMsmw
Resulting in:
$ go run 02.1-09-init.go
Executing init function!
Executing main!
Like any other function, variables declared in init
are only valid there.
Use var
.
var x int
Can be combined for multiple variables:
var x,y int
==var x int, y int
Variables can be initialized.
var a, b int = 10, 20
or
var a int = 10
var b int = 20
If initialized value is present during declaration, type can be omitted:
var sampleInt, sampleBoolean, sampleString = 30, true, "Hello"
or
var sampleInt = 30
var sampleBoolean = true
var sampleString = "Hello"
// 02.1-04-variables.go
package main
import "fmt"
func main() {
var a, b int = 10, 20
var sampleInt, sampleBoolean, sampleString = 30, true, "Hello"
fmt.Println(a, b , sampleInt, sampleBoolean, sampleString)
}
https://play.golang.org/p/TnRrIC43-NR
If no initial value is assigned to a declared variable, it will get a zero
value:
0
for numeric types (int, float, etc.).false
for the boolean type.""
(the empty string) for strings.
Inside a function (including main
), the :=
short assignment statement can be used in place of a var
declaration with implicit type.
Outside a function, every statement begins with a keyword (var
, func
) so the :=
construct is not available.
// 02.1-05-short-declaration.go
package main
import "fmt"
func main() {
sampleInt, sampleBoolean, sampleString := 30, true, "Hello"
fmt.Println(sampleInt, sampleBoolean, sampleString)
}
https://play.golang.org/p/RMC-9h4eBLD
var
statements can be put in different lines (increases readability):
var (
sampleInt = 30
sampleBoolean = true
sampleString = "Hello"
)
Several other Go constructs use the same format. For example import
and const
.
bool
string
int int8 int16 int32 int64 // use int unless you want a specific size
uint uint8 uint16 uint32 uint64 uintptr // ditto, use uint
byte // alias for uint8
rune // alias for int32
// represents a Unicode char
float32 float64
complex64 complex128
Casting needs to be explicit, unlike C where some castings worked out of the box.
// 02.1-06-casting.go
package main
import (
"fmt"
)
func main() {
var a, b int = 20, 30
// Need to convert a and b to float32 before the division
var div float32 = float32(a) / float32(b)
// Cast float32 to int
var divInt = int(div)
fmt.Println(div, divInt)
}
https://play.golang.org/p/wKtudyE9f8q
Declared with const
keyword. Can be character, string, boolean or numeric. Cannot use :=
. Coding standard requires constants to start with a capital letter.
// 02.1-07-const.go
package main
import "fmt"
const Whatever = "whatever"
func main() {
fmt.Println(Whatever)
const One = 1
fmt.Println(One)
}
https://play.golang.org/p/RaNzEnRlFZ4
Multiple constants can be declared together:
const (
Const1 = "Constant String"
Int1 = 12345
True = true
)
Go has two types of strings:
- Interpreted strings: The typical
string
type created with"
. Can contain anything except new line and unescaped"
. - Raw strings: Encoded between "`" (backticks) can contain new lines and other artifacts.
// 02.1-08-rawstring.go
package main
import "fmt"
func main() {
rawstr :=
`First line
some new lines
more new lines
"double quotes"
`
fmt.Print(rawstr)
}
https://play.golang.org/p/D8TwnBhwM0o