01 Golang Basics
01 Golang Basics
You cannot use key words as variables, types, function names in your program
Predeclared names
Variables
Declare a variable in or out of the function
Declare a variable in or out of the function
Example:
var x int
(value will be 0)
Declare a variable in or out of the function
Example:
var x = 5
(type will be int)
Declare a variable in or out of the function
Example:
var (
x1 int = 5
x2 = 8 // type will be the same as x1
)
Declare a variable in the function
name := expression
(short variable declaration, type will be computed)
Can be used only inside a function/method
Example:
x := 5
(type will int)
Naming conventions
• c := 'b'
• i := 0
https://goplay.tools/snippet/xnqb_jHuyNr
• f := 0.0
•
fmt.Printf("String literal - %T\n", s)
• fmt.Printf("Integer literal - %T\n", i)
• fmt.Printf("Character literal - %T\n", c)
• fmt.Printf("Floating number literal - %T\n", f)
• }
Variables in Golang key points
float32 float64
complex64 complex128
Boolean type
• package main true
• false
import (
• "fmt"
• ) Boolean is very simple type, in Golang it is just a
• constant which hold result of two expressions.
func main() {
• // var truthy = true const (
• var truthy bool = 14 > 12 true = 0 == 0 // Untyped bool.
• // var falsy = false false = 0 != 0 // Untyped bool.
•
fmt.Println(truthy)
• fmt.Println(falsy)
• } https://goplay.tools/snippet/b6yluuxtOWk
Logical operators
Numeric types
Signed integer
• func main() { -1 3 5
64 32 64
• var (
• a int = -1
• aSize = unsafe.Sizeof(a) * 8 https://goplay.tools/snippet/JtZ2_7tT0i-
•
b int32 = 3 Machine dependent types:
• bSize = unsafe.Sizeof(b) * 8 int – depending on architecture, take 32/64 bit
• )
•
fmt.Println(a, b, c)
• fmt.Println(bSize, aSize,
cSize)
• }
Compare integers
• func main() { ./prog.go:14:16: invalid operation: a == b
• var ( (mismatched types int and int32)
• a int
./prog.go:15:16: invalid operation: a == c
• b int32
(mismatched types int and int64)
• c int64
• ) https://goplay.tools/snippet/ioHcc7Jzy-H
•
fmt.Println(a == b)
• fmt.Println(b == c) You cannot compare different types of integers,
for example int and int32.
• }
Compare integers
• func main() { true
• var ( true
• a int
• b int32 https://goplay.tools/snippet/CypY4iH
• c int64 ozG8
• )
•
fmt.Println(a == int(b) To compare two different types, we
)
can use type casting.
• fmt.Println(int64(b) ==
c)
• }
Integer binary operators
Increment/Decrement
• func main() { 1
• var a int
0
• a++
-128
• fmt.Println(a)
• -32768
a--
-9223372036854775808
• fmt.Println(a)
• https://goplay.tools/snippet/NBDiiSUtzii
b := int8(math.MaxInt8)
• b++
• fmt.Println(b)
Increment and decrement operation in Golang exists
•
c := int16(math.MaxInt16) only in a suffix-based form, you can write only “i++” not
• c++ “++i”, as well increment operation is mutate value and
• fmt.Println(c)
doesn’t return value of the operation, due to this “j :=
•
d := int64(math.MaxInt64) i++” is invalid operation, as I mentioned before Golang is
• d++ explicit language, you need to write exactly what to
• fmt.Println(d) expect, due to this some common constructions is
• }
forbidden.
Floating-point numbers
Floating point numbers
• func main() { 1
• var f64 float64 1
true
• f64++
• fmt.Println(f64)
• https://goplay.tools/snippet/c07pmPGQMkW
var f32 float32
• f32++ In Golang there is no double and float type,
• fmt.Println(f32) there is only float32 and float64
•
//invalid operation: f32 == f
64 (mismatched types float32 and Float32 occupies 32 bits in memory and stores
float64) values in single-precision floating point
• //fmt.Println(f32 == f64) format.
•
fmt.Println(float64(f32) == f
64) Float64 occupies 64 bits in memory and stores
• } values in double-precision floating point
format.
String type
Strings
• package main Dzień dobry
•
import (
https://goplay.tools/snippet/7yGc4jBf7uQ
• "fmt"
• )
• Why len(msg) returns 12 when we have 11
func main() {
characters? There answer is quite simple,
• msg := "Dzień dobry"
len returns value in bytes, and character
• //msg is a string with
11 characters “ń” cost us 2 bytes in UTF-8 encoding (non-
• ASCI character).
fmt.Println(len(msg)) /
/12
• // Why we have 12 here
?
• }
Converting the string
• package main Dzień dobry
•
import ( https://goplay.tools/snippet/7yGc4jBf7uQ
• "fmt"
• )
•
func main() {
Why len(msg) returns 12 when we have 11
• msg := "Dzień dobry"
characters? There answer is quite simple,
• //msg is a string with
11 characters len returns value in bytes, and character
• “ń” cost us 2 bytes in UTF-8 encoding (non-
fmt.Println(len(msg)) /
/12 ASCI character).
Example:
const x int = 34
Constant declarations
Example:
const x = 5
(type will be untyped integer)
(untyped integer)
Naming conventions
• Begins with a letter (Unicode) or underscore (_);
• May have letters, digits, underscores;
• Case matters: “goLang” and “GoLang” are different names.
• Every constant vithout specified strict type has more weak rules in terms of types system, you
can compare number constant with another constant or variable of any numbered type or aliased
type created from numbered, the same for strings.
• Every constant can have strict type, in this case you cannot compare, assign them to variables of
other type.
Constants
• const name string = "Go" Go
• const ( Java
• e = 2.7182 1.1 1.1 2 2
• pi = 3.1415 float64 int
• ) https://goplay.tools/snippet/O-po3ANlo6u
• const (
• a = 1.1 Constants in Golang are variables that has in
• b place initialization and that value cannot be
• c = 2 changed after first initialization. (One
• d exception, you can in smaller scope define
variable with the same name)
• ) Constants have a little bit different type
• system, strict type of the constant computed when
func main() {
it used, it means that you can compare constant e
• fmt.Println(name)
with float32 and float64 type, as well as
• name := "Java" constant b can be used without type casting with
• fmt.Println(name) any numbered type. The same applicable with type
• aliases(we will talk about it later.)
fmt.Println(a, b, c, d)
• fmt.Printf("%T %T\n", b, d
)
• }
Iota and constants
• type Weekday int
0 1 2
•
const (
0 4 6
• Monday Weekday = iota
• Tuesday = iota
• Wednesday = iota https://goplay.tools/snippet/6DqDZZH1SCi
• )
•
const (
• a = iota * 2 Iota is a constant with special behavior,
• _ it is kind of generator that return unique
• b
sequential number for constant block.
• c
• ) • Value of iota not shared across different
• constants blocks, but
func main() {
• fmt.Println(Monday, Tuesda You can change value of iota using
y, Wednesday) •
• package main 4
• 3
import "fmt" 2
• 1
func main() {
0
• for i := 0; i < 5; i++ {
• defer fmt.Println(i)
• }
•
// deferred funcs run here
• }
https://goplay.tools/snippet/ePn-bHg2S-X
Deferred functions
• package main 10 10 10 10 10 10 10 10 10 10
•
import (
• "fmt" https://goplay.tools/snippet/URnuA-CzSE_V
•)
•
func main() {
• for i := 0; i < 10;
i++ {
• defer func() {
• fmt.Print(i,
" ")
• }()
• }
•}
Deferred functions use cases
https://goplay.tools/snippet/dEShiFiGuCO
Function in Golang key points
• Function is just a bunch of operationgs grouped in a logical way.
• Functions in Golang has type as well, type of the function depending on its
parameters and return statements.
Questions
Flow control
If – else statement
if condition { If else syntax is common for most
languages, the only difference is
... that you don’t need parentheses
around conditions, but the braces
} else if condition{ are required.
...
} else {
...
}
If - else
• func main() {
unexpected error - invalid value, valid
• for i := 0; i <= 7; i++ {
• if weekday, err := isWeekDay(i); er range is [1-7]
r != nil {
1 – true
• fmt.Println("unexpected error -
", err) 2 – true
• } else {
• fmt.Println(i, "-", weekday) 3 – true
• } 4 – true
• } 5 – true
• }
6 – false
•
func isWeekDay(d int) (bool, error) { 7 - false
• if d <= 0 || d > 7 {
• return false, fmt.Errorf("invalid v
alue, valid range is [1-7]")
• } else if d > 5 { https://goplay.tools/snippet/V27mHXgTT42
• return false, nil
• } else {
• return true, nil
• }
• }
Switch statement
• func main() {
• fmt.Println(numberToWeekDay(1)) Monday
• fmt.Println(numberToWeekDay(3)) Wednesday
• }
• func numberToWeekDay(i int) string {
• switch i {
• case 1: https://goplay.tools/snippet/YMHG82I9nFN
• return "Monday"
• case 2:
• return "Tuesday" Switch statement in Golang has pretty
• case 3:
• return "Wednesday" common syntax, one important difference
• case 4:
• return "Thursday" is that instead of falltrough behavior,
• case 5: Golang breaks after each case.
• return "Friday"
• case 6:
• return "Saturday"
• case 7:
• return "Sunday"
•
default:
• return "unknown"
• }
• }
Switch statement
• func main() {
• fmt.Println(isWeekDay(1)) true <nil>
• false <nil>
fmt.Println(isWeekDay(6))
•
fmt.Println(isWeekDay(10)) false invalid value, valid range [1-7]
• }
•
func isWeekDay(i int) (bool, error) {
https://goplay.tools/snippet/SMVOi9WLJag
• switch i {
• case 1, 2, 3, 4, 5:
• return true, nil
• case 6, 7: In case you have the same behaviour for
• return false, nil multiple values, you can specify multiple
• default:
values in one case.
• return false, fmt.Errorf("invalid v
alue, valid range [1-7]")
• }
• }
Switch statement
• func main() {
true <nil>
• fmt.Println(isWeekend(6))
• false <nil>
fmt.Println(isWeekend(5))
• false invalid value, valid range [1-7]
fmt.Println(isWeekend(10))
• }
•
func isWeekend(i int) (bool, error) { https://goplay.tools/snippet/xENCYSAAXeu
•
switch {
• case i >= 6 && i <= 7:
• return true, nil You can implement all use-cases of if-
• case i >= 1 && i <= 5:
else statement using switch statement, in
• return false, nil
• default: case of absence of variable in switch you
• return false, fmt.Errorf("invalid v can just specify expression with boolean
alue, valid range [1-7]")
• } result.
• }
Questions
Loops
Loops (Plain old for loop)
• package main 0 1 2 3 4 5 6 7 8 9
•
import ( https://goplay.tools/snippet/KEBAFKZvwvx
• "fmt"
Plain for loop syntax is common for most
• ) languages, the only difference is that
• you don’t need parentheses around
func main() { conditions, but the braces are required.
• for i := 0; i < 10; i++ {
• fmt.Print(i, " ")
• }
• }
Loops (While loop)
• package main 0 1 2 3 4 5 6 7 8 9
•
import ( https://goplay.tools/snippet/Fbp11kKVQw4
• "fmt"
In Golang while loop is special type of
• )
for loop.
•
func main() {
• var i int
• for i < 10 {
• fmt.Print(i, " ")
• i++
• }
• }
Loops (Infinite loop)
• package main Hello from infinite loop
• Hello from infinite loop
import (
Hello from infinite loop
• "fmt"
Hello from infinite loop
• )
Hello from infinite loop
•
func main() { ...
•
for {
https://goplay.tools/snippet/AhPisV44upd
• fmt.Println("Hello from i
nfinite loop")
• } Empty values works as infinite loop
• }
Loops (For each)
• func main() { Hello from for-each loop !
• strs := []string{
• "Hello", https://goplay.tools/snippet/JvDY6ZHkrUY
• "from",
• "for-each", For range loop is helpful do go over
• "loop", collections, range key word used, first
• "!", parameter returned by range is index of
• Loop variable initialized only once; you need to copy it before using in
closures or path to a function in case it reference type.
greeting/
├── go.mod
├── main.go
└── language
├── polish
│ └── polish.go
├── english
│ └── english.go
└── language.go
Golang packages
github.com/burov/greeting/language/polish
package polish
~/go/src/github.com/burov: const Name = ”Polish"
greeting/
├── go.mod
├── main.go github.com/burov/greeting/language/english
└── language
├── polish package english
│ └── polish.go
├── english const Name = "English"
│ └── english.go
└── language.go
github.com/burov/greeting/language
package language
import (
"fmt" github.com/burov/greeting/language/deutsch
"github.com/burov/greeting/language"
package deutsch
"github.com/burov/greeting/language/english"
~/go/src/github.com/burov: ) const Name = "Deutsch"
github.com/burov/greeting/language
package language
~/go/src/github.com/burov:
greeting/
├── go.mod
├── main.go
└── language github.com/burov/greeting/language/english
├── polish
│ └── polish.go package english
├── english
│ └── english.go const Name = "English"
const internalName = "eng"
└── language.go
Exported/unexported objects
package main
import (
"fmt"
"github.com/burov/greeting/language/english"
)
~/go/src/github.com/burov:
func main() {
greeting/ fmt.Println(english.Name)
├── go.mod fmt.Println(english.internalName)
├── main.go } github.com/burov/greeting/language/english
└── language
├── polish package english
│ └── polish.go
├── english const Name = "English"
const internalName = "en"
│ └── english.go
└── language.go
Exported/unexported objects
package main
import (
"fmt"
"github.com/burov/greeting/language/polish"
)
~/go/src/github.com/burov: