0% found this document useful (0 votes)
16 views32 pages

Golang Basics: Syntax, Commands, and Types

The document provides an overview of the basics of Golang, highlighting its simple syntax, rich standard library, and support for concurrency. It covers essential commands, variable types, functions, structs, interfaces, flow control, and collections like slices and maps. Additionally, it explains channel operations, including buffered and unbuffered channels, and demonstrates the use of goroutines and synchronization with wait groups.

Uploaded by

bigbossmerong
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views32 pages

Golang Basics: Syntax, Commands, and Types

The document provides an overview of the basics of Golang, highlighting its simple syntax, rich standard library, and support for concurrency. It covers essential commands, variable types, functions, structs, interfaces, flow control, and collections like slices and maps. Additionally, it explains channel operations, including buffered and unbuffered channels, and demonstrates the use of goroutines and synchronization with wait groups.

Uploaded by

bigbossmerong
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Week 2

Golang: Basics
Why Golang
• Simple and readable syntax
• This is important for reviews
• Rich standard library for I/O, http etc.
• First class citizen support for concurrency
• Decent-ish garbage collection
• Statically typed
Essential Go Commands
• go run
• Runs the code
• go build
• Compiles and builds the code into a native binary
• go mod
• Manage dependencies
• go fmt
• Formats the code
• go test
• Runs tests
Hello World
// this is the main entry point
// in Golang, package main is special
// typically, packages should follow the folder name
package main

// dependencies to import
import (
// these follow file paths
"fmt"
)

// program execution begins here


func main() {
[Link]("hello world")
}
How does imports work?
• Standard Library
• E.g. fmt, strings
• Go automatically resolves it
• Third-party modules
• Go downloads third party modules (go get …) if they are not in local
cache.
• Cache is defined modules cache $HOME/go/pkg/mod
• Local files
• Go will resolve packages by its folder structure relative to module root
(defined by [Link])
Variable types
// package level variable
// it can be accessed by any code that has the same package
var a = 0
func main() {
[Link](a)
// declaration with initialization: initializes to default value
var b string
[Link](b)
// short way to declare variables, used only in fns or blocks
c := 1
[Link](c)
// type is inferred by compiler: a.k.a *magic*
d := "this is a string"
[Link](d)
}
Functions
func divide(a, b int) (int, error) {
if b == 0 {
return 0, [Link]("division by zero")
}
return a / b, nil
}
Structs
// Basic struct declaration
type Person struct {
Name string
Age int
}
// Method with value receiver (non-pointer)
func (p Person) Greet() string {
return [Link]("Hello, my name is %s and I am %d years old.", [Link], [Link])
}
// Method with pointer receiver
func (p *Person) HaveBirthday() {
[Link]++ // Modifies the original struct
}
// Composition using structs
type Employee struct {
Person // Embedded struct (composition)
Position string
}
More structs
p := Person{Name: "Alice", Age: 30}

// Access fields and call methods


[Link]([Link]) // Output: Alice
[Link]([Link]()) // Call method with value receiver

// Call method with pointer receiver


[Link]() // Increases age by 1
[Link]([Link]()) // Output: Hello, my name is Alice and I am 31 years old.

// Using a pointer to a struct with &


pPointer := &p
[Link]()
[Link]([Link]()) // Output: Hello, my name is Alice and I am 32
years old.
More More structs
// Using the `new` keyword
pNew := new(Person) // Allocates memory and returns a pointer. This initialises
to default value
[Link]([Link]()) // Output: Hello, my name is and I am 0 years old.

// Set explicitly
[Link] = "Bob"
[Link] = 25

[Link]([Link]()) // Output: Hello, my name is Bob and I am 25 years


old.
[Link]()
[Link]([Link]()) // Output: Hello, my name is Bob and I am 26 years
old.
Inheritance? Composition
// Using composition
e := Employee{
Person: Person{Name: "Charlie", Age: 40},
Position: "Manager",
}

// Access fields and methods from embedded struct


[Link]([Link]) // Output: Charlie (inherited from Person)
[Link]([Link]()) // Output: Hello, my name is Charlie and I am 40 years
old.
// Modify the embedded struct's fields
[Link]() // Method of embedded Person struct
[Link]([Link]()) // Output: Hello, my name is Charlie and I am 41 years
old.
Polymorphism? Interface!
type Animal interface {
Greet() string
}

type Dog struct{}

func (d Dog) Greet() string {


return "Woof!"
}
More Interface
func main() {
person := Person{Name: "Alice", Age: 30}
dog := Dog{}

GiveGreeting(person)
GiveGreeting(dog)
}

func GiveGreeting(a Animal) {


[Link]([Link]())
}
Flow Control: if
func main() {
x := 10
if x > 5 {
[Link]("x is greater than 5")
} else if x == 5 {
[Link]("x is equal to 5")
} else {
[Link]("x is less than 5")
}
}
Collections: Slice - Declaration
slice := make([]int, 5) // Length 5, default values
[Link]("Slice:", slice, "Length:", len(slice), "Capacity:", cap(slice))

literalSlice := []int{1, 2, 3, 4, 5}
[Link]("Literal Slice:", literalSlice)

noLengthSlice := []int{}
[Link]("No Length Slice:", noLengthSlice, "Length:", len(noLengthSlice),
"Capacity:", cap(noLengthSlice))
Collections: Slice - Intervals
array := [5]int{10, 20, 30, 40, 50}
sliceFromArray := array[1:4] // Slicing an array
[Link]("Slice from Array:", sliceFromArray)

// Slice Intervals
[Link]("Original Array: %v\n", array)
sliceFromArray[0] = 99 // Modifies the underlying array
[Link]("Modified Slice:", sliceFromArray)
[Link]("Modified Array:", array)
Collection: Slice - Operations
// Append
appendedSlice := append(slice, 10, 20)
[Link]("Appended Slice:", appendedSlice)
[Link]("Original Slice (unchanged):", slice)

// Copy
src := []int{1, 2, 3}
dst := make([]int, len(src))
copy(dst, src)
[Link]("Source Slice:", src, "Copied Slice:", dst)
Collection: Slice – nil vs empty
// Nil (initial value) vs empty
var nilSlice []int
emptySlice := []int{}
[Link]("Nil Slice:", nilSlice, "Is nil?", nilSlice == nil)
[Link]("Empty Slice:", emptySlice, "Is nil?", emptySlice == nil)
[Link]("Length of nil slice:", len(nilSlice))
[Link]("Length of empty slice:", len(emptySlice))
Collections: Maps
func main() {
capitals := make(map[string]string)
capitals["France"] = "Paris"
[Link](capitals["France"])

value, ok := capitals["Germany"]
if ok {
[Link](value)
} else {
capitals["Germany"] = "Berlin"
}

for key, value := range capitals {


[Link](key, value)
}
}
Flow Control: for
func main() {
for i := 0; i < 5; i++ { // Initialize i to 0; repeat until i >= 5
[Link]("i =", i)
}

nums := []int{1, 2, 3, 4}
for index, value := range nums { // Iterate over slice `nums`
[Link]("Index: %d, Value: %d\n", index, value)
}

}
Flow control: defer
func main() {
defer [Link]("This will run last")
[Link]("This will run first")
}
Flow control: select
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
[Link](2 * [Link])
ch1 <- "Hello from ch1"
}()
go func() {
[Link](1 * [Link])
ch2 <- "Hello from ch2"
}()
select {
case msg1 := <-ch1: // Receives a message from ch1
[Link](msg1)
case msg2 := <-ch2: // Receives a message from ch2
[Link](msg2)
case <-[Link](3 * [Link]): // Timeout case
[Link]("Timeout!")
}
}
go func?
go func(parameters) {
// Code to execute concurrently
}(arguments)

func main() {
message := "Hello from goroutine!"

go func(msg string) {
[Link](msg)
}(message)

[Link]("Hello from main!")


[Link](1 * [Link]) // Wait to ensure goroutine finishes
}
Go func: Waitgroup
func main() {
var wg [Link]

[Link](1) // Add one goroutine to the WaitGroup

go func() {
defer [Link]() // Mark the goroutine as done
[Link]("Hello from goroutine!")
}()

[Link]("Hello from main!")


[Link]() // Wait for all goroutines to finish
}
Go func: Channel
func main() {
done := make(chan bool) // Create a channel

go func() {
[Link]("Hello from goroutine!")
done <- true // Send a signal on the channel
}()

[Link]("Hello from main!")


<-done // Wait to receive the signal
}
Channel-chan?
Channels are essentially just pipes. It is directional.

func sendMessage(ch chan string) {


ch <- "Hello from Goroutine!” // Sends a value into channel
}

func main() {
ch := make(chan string) // Create a string channel

go sendMessage(ch) // Start goroutine

msg := <-ch // Receives a value from channel


[Link](msg)
}
Channel: Unbuffered
func main() {
ch := make(chan int) // Creating an unbuffered channel.
// A goroutine to send a value.
go func() {
[Link]("Ready to send 42...")
ch <- 42
[Link]("42 is sent.")
}()

// Waiting to get the value from the channel.


[Link]("Waiting for value from channel...")
val := <-ch
[Link]("Value received:", val)
}
Main() ”Waiting for value…” val := <-ch val := 42 “Value Received”

”Ready to send 42” ch <- 42 “42 is sent”


Channel: Closed
func chanEx2() {
// Closed channel
ch := make(chan int)
close(ch)
v, ok := <-ch
[Link](v, ok) // 0 false
}
Channel: Buffered
func main() {
ch := make(chan int, 3)
go func() {
[Link]("Goroutine: Waiting for a value from the channel...")
// pops the first element 1, out of the channel
[Link]("Goroutine: Got the value %d from the channel.\n", <-ch)
}()
// Populating the buffered channel to its limit.
ch <- 1
ch <- 2
ch <- 3
[Link]("Buffer is now full.")
// Goroutine shld run here
// After goroutine prints, 4 is inserted
ch <- 4
// Prints
[Link]("This line prints after the 4th value gets through.")
}
Channel: Nil
var ch chan int // nil

go func() {
ch <- 42 // block
}()

value := <-ch // block


Channel: Summary
Operation Unbuffered Buffered Closed Nil

Send if receiver is Send if space is


Send Value available, else available, else PANIC Blocks
blocks blocks

Receives if data is Receives if data is


Receive Value available, else available, else 0 value Blocks
blocks blocks

Close Close Close PANIC PANIC

You might also like