├── go.mod
├── images
└── golang.png
├── 001_hello_world
├── main.go
└── README.md
├── .idea
├── misc.xml
├── vcs.xml
├── .gitignore
└── modules.xml
├── 026_sorting
├── 002_sorting_strings
│ ├── 002_sorting_strings.go
│ └── README.md
├── 001_basic_sorting_with_integers
│ ├── 001_basic_sorting_with_integers.go
│ └── README.md
├── 006_reverse_sorting
│ ├── 006_reverse_sorting.go
│ └── README.md
├── 008_sorting_a_map_by_keys
│ ├── 008_sorting_a_map_by_keys.go
│ └── README.md
├── 003_sorting_by_custom_slice
│ ├── 003_sorting_by_custom_slice.go
│ └── README.md
├── 007_sorting_with_custom_comparator_function
│ ├── 007_sorting_with_custom_comparator_function.go
│ └── README.md
├── 010_concurrent_sorting_with_goroutines
│ ├── 010_concurrent_sorting_with_goroutines.go
│ └── README.md
├── 004_sorting_by_multiple_fields
│ ├── 004_sorting_by_multiple_fields.go
│ └── README.md
├── 009_sorting_a_map_by_values
│ ├── 009_sorting_a_map_by_values.go
│ └── README.md
└── 005_sorting_a_custom_type_using_sort_interface
│ ├── 005_sorting_a_custom_type_using_sort_interface.go
│ └── README.md
├── 027_panic_and_defer
├── 001_basic_example_of_defer
│ ├── 001_basic_example_of_defer.go
│ └── README.md
├── 002_multiple_defer
│ ├── 002_multiple_defer.go
│ └── README.md
├── 004_basic_example_of_panic
│ ├── 004_basic_example_of_panic.go
│ └── README.md
├── 008_defer_log_functions_exit
│ ├── 008_defer_log_functions_exit.go
│ └── README.md
├── 006_panic_with_defer
│ ├── 006_panic_with_defer.go
│ └── README.md
├── 009_closing_resources_with_defer
│ ├── 009_closing_resources_with_defer.go
│ └── README.md
├── 010_defer_with_https_requests
│ ├── 010_defer_with_https_requests.go
│ └── README.md
├── 003_defer_with_function_call
│ ├── 003_defer_with_function_call.go
│ └── README.md
├── 007_chain_panic_and_defer
│ ├── 007_chain_panic_and_defer.go
│ └── README.md
└── 005_panic_with_recover
│ ├── 005_panic_with_recover.go
│ └── README.md
├── go_sample_examples.iml
├── 020_timers
├── 001_simple_timer
│ ├── 001_simple_timer.go
│ └── README.md
├── 004_using_time_after
│ ├── 004_using_time_after.go
│ └── README.md
├── 003_reset_timer
│ ├── 003_reset_timer.go
│ └── README.md
├── 005_timer_with_select
│ ├── 005_timer_with_select.go
│ └── README.md
└── 002_stop_timer
│ ├── 002_stop_timer.go
│ └── README.md
├── 023_waitgroup
├── 002_waitGroup_with_anonymous_functions
│ ├── 002_waitGroup_with_anonymous_functions.go
│ └── README.md
├── 001_basic_waitgroup
│ ├── 001_basic_waitgroup.go
│ └── README.md
├── 004_waitgroup_with_error_handling
│ ├── 004_waitgroup_with_error_handling.go
│ └── README.md
└── 003_waitgroup_with_multiple_waits
│ └── 003_waitgroup_with_multiple_waits.go
├── 030_json
├── 001_basic_encoding_json
│ ├── 001_basic_encoding_json.go
│ └── README.md
├── 006_omitting_empty_fields
│ ├── 006_omitting_empty_fields.go
│ └── README.md
├── 005_custom_json_field_names
│ ├── 005_custom_json_field_names.go
│ └── README.md
├── 002_basic_decoding_json
│ ├── 002_basic_decoding_json.go
│ └── README.md
├── 010_streaming_json_encoding
│ ├── 010_streaming_json_encoding.go
│ └── README.md
├── 008_decoding_json_into_a_map_string_interface
│ ├── 008_decoding_json_into_a_map_string_interface.go
│ └── README.md
├── 004_working_with_json_arrays
│ ├── 004_working_with_json_arrays.go
│ └── README.md
├── 003_handling_nested_json_structures
│ ├── 003_handling_nested_json_structures.go
│ └── README.md
├── 009_decoding_json_with_unknown_fields
│ └── 009_decoding_json_with_unknown_fields.go
└── 007_custom_json_marshaling_and_unmarshaling
│ └── 007_custom_json_marshaling_and_unmarshaling.go
├── 019_range_over_channel
├── 003_buffered_channels_with_range
│ ├── 003_buffered_channels_with_range.go
│ └── README.md
├── 001_basic_example_range_over_channel
│ ├── 001_basic_example_range_over_channel.go
│ └── README.md
└── 002_multiple_goroutines_sending_to_a_channel
│ └── 002_multiple_goroutines_sending_to_a_channel.go
├── 025_atomic_counters
├── 005_atomic_pointer
│ ├── 005_atomic_pointer.go
│ └── README.md
├── 001_basic_atomic_counter_using_sync_atomic
│ ├── 001_basic_atomic_counter_using_sync_atomic.go
│ └── README.md
├── 003_atomic_flag_using_sync_atomic
│ ├── 003_atomic_flag_using_sync_atomic.go
│ └── README.md
├── 004_atomic_counter_with_load_and_store_operations
│ ├── 004_atomic_counter_with_load_and_store_operations.go
│ └── README.md
└── 002_ atomic_counter _with_decrement_and_compare_and_swap
│ ├── 002_ atomic_counter _with_decrement_and_compare_and_swap.go
│ └── README.md
├── 024_rate_limiter
├── 003_custom_rate_limiter_using_time_after
│ ├── 003_custom_rate_limiter_using_time_after.go
│ └── README.md
├── 001_basic_rate_limiter
│ ├── 001_basic_rate_limiter.go
│ └── README.md
├── 005_rate_limiter_with_time_newticker
│ ├── 005_rate_limiter_with_time_newticker.go
│ └── README.md
├── 004_rate_limiter_with_context
│ ├── 004_rate_limiter_with_context.go
│ └── README.md
└── 002_rate_limiter_burst_capacity
│ ├── 002_rate_limiter_burst_capacity.go
│ └── README.md
├── 018_closing_channel
├── 05_panic_when_closing_an_already_closed_channel
│ ├── 05_panic_when_closing_an_already_closed_channel.go
│ └── README.md
├── 01_basic_channel_closing
│ ├── 01_basic_channel_closing.go
│ └── README.md
├── 04_sending_a_signal_with_a_closed_channel
│ ├── 04_sending_a_signal_with_a_closed_channel.go
│ └── README.md
├── 02_detecting_closed_channel
│ ├── 02_detecting_closed_channel.go
│ └── README.md
└── 03_closing_channels_in_multiple_goroutines
│ └── 03_closing_channels_in_multiple_goroutines.go
├── 021_tickers
├── 01_basic_ticker
│ ├── 01_basic_ticker.go
│ └── README.md
├── 05_ticker_with_limited_ticks
│ ├── 05_ticker_with_limited_ticks.go
│ └── README.md
├── 03_ticker_with_select
│ ├── 03_ticker_with_select.go
│ └── README.md
├── 02_stop_ticker
│ ├── 02_stop_ticker.go
│ └── README.md
└── 04_reset_ticker
│ ├── 04_reset_ticker.go
│ └── README.md
├── 029_text_samples
├── 005_template_with_data_formatting
│ ├── 005_template_with_data_formatting.go
│ └── README.md
├── 002_loops_in_templates
│ ├── 002_loops_in_templates.go
│ └── README.md
├── 001_conditional_logic_in_templates
│ ├── 001_conditional_logic_in_templates.go
│ └── README.md
├── 003_template_functions
│ ├── 003_template_functions.go
│ └── README.md
├── 004_nested_templates
│ ├── 004_nested_templates.go
│ └── README.md
└── 006_complex_structs_and_template_actions
│ ├── 006_complex_structs_and_template_actions.go
│ └── README.md
├── .gitignore
├── 022_worker_pools
├── 002_worker_pool_with_buffered_channels
│ └── 002_worker_pool_with_buffered_channels.go
├── 001_basic_worker_pool
│ └── 001_basic_worker_pool.go
├── 004_dynamic_worker_pool
│ └── 004_dynamic_worker_pool.go
├── 003_worker_pool_with_error_handling
│ └── 003_worker_pool_with_error_handling.go
└── 005_rate_limited_worker_pool
│ └── 005_rate_limited_worker_pool.go
├── 002_variables
└── main.go
├── 005_function
└── main.go
└── 028_string_manipulations
└── 001_string_manipulations.go
/go.mod:
--------------------------------------------------------------------------------
1 | module go_sample_examples
2 |
--------------------------------------------------------------------------------
/images/golang.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Rapter1990/go_sample_examples/HEAD/images/golang.png
--------------------------------------------------------------------------------
/001_hello_world/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | fmt.Println("Merhaba Dünya!")
7 | }
8 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/026_sorting/002_sorting_strings/002_sorting_strings.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sort"
6 | )
7 |
8 | func main() {
9 | strings := []string{"banana", "apple", "cherry"}
10 | sort.Strings(strings)
11 | fmt.Println("Sorted strings:", strings)
12 | }
13 |
--------------------------------------------------------------------------------
/026_sorting/001_basic_sorting_with_integers/001_basic_sorting_with_integers.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sort"
6 | )
7 |
8 | func main() {
9 | numbers := []int{5, 2, 6, 3, 1, 4}
10 | sort.Ints(numbers)
11 | fmt.Println("Sorted integers:", numbers)
12 | }
13 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/026_sorting/006_reverse_sorting/006_reverse_sorting.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sort"
6 | )
7 |
8 | func main() {
9 |
10 | // Demonstrates how to sort in reverse order
11 |
12 | numbers := []int{5, 2, 6, 3, 1, 4}
13 | sort.Sort(sort.Reverse(sort.IntSlice(numbers)))
14 | fmt.Println("Reverse sorted integers:", numbers)
15 | }
16 |
--------------------------------------------------------------------------------
/027_panic_and_defer/001_basic_example_of_defer/001_basic_example_of_defer.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | func main() {
8 |
9 | // The defer statement is used to delay the execution of a function until the surrounding function returns
10 |
11 | defer fmt.Println("This is deferred")
12 | fmt.Println("This happens first")
13 | }
14 |
--------------------------------------------------------------------------------
/go_sample_examples.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/027_panic_and_defer/002_multiple_defer/002_multiple_defer.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | func main() {
8 |
9 | // multiple defer statements are used, they are executed in Last In, First Out (LIFO) order
10 |
11 | defer fmt.Println("First defer")
12 | defer fmt.Println("Second defer")
13 | defer fmt.Println("Third defer")
14 | fmt.Println("Executing main function")
15 | }
16 |
--------------------------------------------------------------------------------
/027_panic_and_defer/004_basic_example_of_panic/004_basic_example_of_panic.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | func main() {
8 |
9 | // The panic function is used to stop the ordinary flow of control and start panicking,
10 | // which in turn begins unwinding the stack
11 |
12 | fmt.Println("Start of main")
13 | panic("Something went wrong")
14 | fmt.Println("This will not be printed")
15 | }
16 |
--------------------------------------------------------------------------------
/027_panic_and_defer/008_defer_log_functions_exit/008_defer_log_functions_exit.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | func main() {
8 | defer exitLog("main")
9 | fmt.Println("Main function running")
10 | performTask()
11 | }
12 |
13 | func performTask() {
14 | defer exitLog("performTask")
15 | fmt.Println("Task performed")
16 | panic("Panic in performTask")
17 | }
18 |
19 | func exitLog(funcName string) {
20 | fmt.Printf("Exiting %s\n", funcName)
21 | }
22 |
--------------------------------------------------------------------------------
/027_panic_and_defer/006_panic_with_defer/006_panic_with_defer.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | func main() {
8 |
9 | // Deferred functions will still run even if a panic occurs. This is useful for cleanup tasks
10 |
11 | defer fmt.Println("This will run even if panic occurs")
12 | panic("Panic in main function")
13 | fmt.Println("This will not be printed")
14 |
15 | /*
16 | This will run even if panic occurs
17 | panic: Panic in main function
18 |
19 | */
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/027_panic_and_defer/009_closing_resources_with_defer/009_closing_resources_with_defer.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | )
7 |
8 | func main() {
9 |
10 | // This example demonstrates using defer to ensure resources like files are closed properly, even if an error occurs
11 |
12 | file, err := os.Open("example.txt")
13 | if err != nil {
14 | panic(err)
15 | }
16 | defer file.Close()
17 |
18 | fmt.Println("File opened successfully")
19 | // Processing file content...
20 | }
21 |
--------------------------------------------------------------------------------
/020_timers/001_simple_timer/001_simple_timer.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | // Basic Example: Simple Timer
11 | // Create a basic timer that fires after 2 seconds
12 |
13 | // Create a timer that will fire after 2 seconds
14 | timer := time.NewTimer(2 * time.Second)
15 |
16 | fmt.Println("Waiting for the timer to fire...")
17 |
18 | // Block until the timer's channel sends a value
19 | <-timer.C
20 |
21 | fmt.Println("Timer fired!")
22 | }
23 |
--------------------------------------------------------------------------------
/027_panic_and_defer/010_defer_with_https_requests/010_defer_with_https_requests.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "io"
6 | "net/http"
7 | )
8 |
9 | func main() {
10 |
11 | // using defer to close the response body of an HTTP request
12 |
13 | resp, err := http.Get("https://www.google.com")
14 | if err != nil {
15 | panic(err)
16 | }
17 | defer resp.Body.Close()
18 |
19 | body, err := io.ReadAll(resp.Body)
20 | if err != nil {
21 | panic(err)
22 | }
23 | fmt.Println(string(body))
24 | }
25 |
--------------------------------------------------------------------------------
/027_panic_and_defer/003_defer_with_function_call/003_defer_with_function_call.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | )
7 |
8 | func main() {
9 |
10 | // use defer to call a function that cleans up resources, such as closing a file
11 |
12 | file, err := os.Create("example.txt")
13 | if err != nil {
14 | panic(err)
15 | }
16 | defer file.Close()
17 |
18 | _, err = file.WriteString("Hello, Go!")
19 | if err != nil {
20 | panic(err)
21 | }
22 | fmt.Println("File written successfully")
23 | }
24 |
--------------------------------------------------------------------------------
/027_panic_and_defer/007_chain_panic_and_defer/007_chain_panic_and_defer.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | func main() {
8 |
9 | // You can chain panic and recover to allow partial recovery and continue execution after a panic
10 |
11 | defer func() {
12 | if r := recover(); r != nil {
13 | fmt.Println("Recovered in main:", r)
14 | panic("panic again")
15 | }
16 | }()
17 | funcThatPanics()
18 | fmt.Println("This will not be printed")
19 | }
20 |
21 | func funcThatPanics() {
22 | panic("Original panic")
23 | }
24 |
--------------------------------------------------------------------------------
/020_timers/004_using_time_after/004_using_time_after.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | // Using time.After
11 | // time.After is a simpler alternative to time.NewTimer for creating a timer that only needs to fire once.
12 | // It returns a channel that will receive the current time after the specified duration.
13 |
14 | fmt.Println("Waiting for 2 seconds...")
15 |
16 | // Wait for 2 seconds using time.After
17 | <-time.After(2 * time.Second)
18 |
19 | fmt.Println("2 seconds passed.")
20 | }
21 |
--------------------------------------------------------------------------------
/026_sorting/008_sorting_a_map_by_keys/008_sorting_a_map_by_keys.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sort"
6 | )
7 |
8 | func main() {
9 |
10 | // Show how to sort a map by its keys
11 |
12 | ages := map[string]int{
13 | "Alice": 25,
14 | "Charlie": 20,
15 | "Bob": 30,
16 | }
17 |
18 | keys := make([]string, 0, len(ages))
19 | for k := range ages {
20 | keys = append(keys, k)
21 | }
22 |
23 | sort.Strings(keys)
24 |
25 | fmt.Println("Sorted by keys:")
26 | for _, k := range keys {
27 | fmt.Println(k, ages[k])
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/026_sorting/003_sorting_by_custom_slice/003_sorting_by_custom_slice.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sort"
6 | )
7 |
8 | type Person struct {
9 | Name string
10 | Age int
11 | }
12 |
13 | func main() {
14 |
15 | // Show how to sort a slice of structs by a custom field, like sorting by Age
16 |
17 | people := []Person{
18 | {"Alice", 25},
19 | {"Bob", 30},
20 | {"Charlie", 20},
21 | }
22 |
23 | sort.Slice(people, func(i, j int) bool {
24 | return people[i].Age < people[j].Age
25 | })
26 |
27 | fmt.Println("Sorted by age:", people)
28 | }
29 |
--------------------------------------------------------------------------------
/023_waitgroup/002_waitGroup_with_anonymous_functions/002_waitGroup_with_anonymous_functions.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | )
7 |
8 | func main() {
9 |
10 | // WaitGroup with Anonymous Functions
11 | // Demonstrates using a WaitGroup with an anonymous function
12 |
13 | var wg sync.WaitGroup
14 | n := 5
15 |
16 | for i := 1; i <= n; i++ {
17 | wg.Add(1)
18 | go func(id int) {
19 | defer wg.Done()
20 | fmt.Printf("Worker %d is processing\n", id)
21 | }(i)
22 | }
23 |
24 | // Wait for all workers to finish
25 | wg.Wait()
26 | fmt.Println("All workers completed.")
27 | }
28 |
--------------------------------------------------------------------------------
/030_json/001_basic_encoding_json/001_basic_encoding_json.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | )
7 |
8 | type Person struct {
9 | Name string
10 | Age int
11 | Country string
12 | }
13 |
14 | func main() {
15 |
16 | // This example shows how to convert a Go struct into JSON format using json.Marshal
17 |
18 | person := Person{
19 | Name: "John",
20 | Age: 30,
21 | Country: "USA",
22 | }
23 |
24 | jsonData, err := json.Marshal(person)
25 | if err != nil {
26 | fmt.Println("Error encoding JSON:", err)
27 | return
28 | }
29 |
30 | fmt.Println(string(jsonData))
31 | }
32 |
--------------------------------------------------------------------------------
/019_range_over_channel/003_buffered_channels_with_range/003_buffered_channels_with_range.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | func main() {
8 |
9 | // Buffered Channels with Range
10 | // Combine buffered channels with range to control the flow of data
11 |
12 | ch := make(chan int, 3) // Create a buffered channel
13 |
14 | // Send values to the buffered channel
15 | ch <- 1
16 | ch <- 2
17 | ch <- 3
18 |
19 | close(ch) // Close the channel
20 |
21 | // Receive values using range
22 | for value := range ch {
23 | fmt.Println("Received:", value)
24 | }
25 |
26 | fmt.Println("Channel closed, no more data.")
27 | }
28 |
--------------------------------------------------------------------------------
/025_atomic_counters/005_atomic_pointer/005_atomic_pointer.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync/atomic"
6 | )
7 |
8 | func main() {
9 |
10 | // Atomic Pointer
11 | // demonstrate how to atomically load and store a pointer value
12 |
13 | var data atomic.Value
14 |
15 | // Store an initial value
16 | data.Store("Initial Value")
17 |
18 | // Load and print the current value
19 | fmt.Println("Current Value:", data.Load())
20 |
21 | // Start a goroutine to change the value
22 | go func() {
23 | data.Store("New Value")
24 | }()
25 |
26 | // Load and print the new value
27 | fmt.Println("New Value:", data.Load())
28 | }
29 |
--------------------------------------------------------------------------------
/024_rate_limiter/003_custom_rate_limiter_using_time_after/003_custom_rate_limiter_using_time_after.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | // Custom Rate Limiting Using time.After
11 | // Show a more flexible approach where each request is rate-limited individually.
12 |
13 | requests := make(chan int, 5)
14 |
15 | for i := 1; i <= 5; i++ {
16 | requests <- i
17 | }
18 | close(requests)
19 |
20 | for req := range requests {
21 | // Delay processing each request by 200 milliseconds
22 | time.Sleep(200 * time.Millisecond)
23 | fmt.Println("Request", req, "processed at", time.Now())
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/026_sorting/007_sorting_with_custom_comparator_function/007_sorting_with_custom_comparator_function.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sort"
6 | )
7 |
8 | type Person3 struct {
9 | Name string
10 | Age int
11 | }
12 |
13 | func main() {
14 |
15 | // Sort a slice of structs with a custom comparator, which provides greater flexibility
16 |
17 | people := []Person3{
18 | {"Alice", 25},
19 | {"Bob", 30},
20 | {"Charlie", 20},
21 | }
22 |
23 | // Custom sort by Name length
24 | sort.Slice(people, func(i, j int) bool {
25 | return len(people[i].Name) < len(people[j].Name)
26 | })
27 |
28 | fmt.Println("Sorted by name length:", people)
29 | }
30 |
--------------------------------------------------------------------------------
/030_json/006_omitting_empty_fields/006_omitting_empty_fields.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | )
7 |
8 | type Person6 struct {
9 | Name string `json:"name"`
10 | Age int `json:"age,omitempty"`
11 | Country string `json:"country,omitempty"`
12 | }
13 |
14 | func main() {
15 |
16 | // This example shows how to omit empty fields from the JSON output using the omitempty struct tag
17 |
18 | person := Person6{
19 | Name: "John Doe",
20 | }
21 |
22 | jsonData, err := json.Marshal(person)
23 | if err != nil {
24 | fmt.Println("Error encoding JSON:", err)
25 | return
26 | }
27 |
28 | fmt.Println(string(jsonData))
29 | }
30 |
--------------------------------------------------------------------------------
/024_rate_limiter/001_basic_rate_limiter/001_basic_rate_limiter.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | // Basic Rate Limiting Using time.Tick
11 | // Show how to limit the processing of requests to one every 200 milliseconds.
12 |
13 | requests := make(chan int, 5)
14 |
15 | for i := 1; i <= 5; i++ {
16 | requests <- i
17 | }
18 | close(requests)
19 |
20 | // Create a rate limiter that ticks every 200 milliseconds
21 | limiter := time.Tick(200 * time.Millisecond)
22 |
23 | for req := range requests {
24 | <-limiter // Wait for the next tick
25 | fmt.Println("Request", req, "processed at", time.Now())
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/026_sorting/010_concurrent_sorting_with_goroutines/010_concurrent_sorting_with_goroutines.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sort"
6 | "sync"
7 | )
8 |
9 | func sortSlice(slice []int, wg *sync.WaitGroup) {
10 | defer wg.Done()
11 | sort.Ints(slice)
12 | fmt.Println("Sorted slice:", slice)
13 | }
14 |
15 | func main() {
16 |
17 | // Use goroutines to sort multiple slices concurrently
18 |
19 | var wg sync.WaitGroup
20 |
21 | slices := [][]int{
22 | {3, 2, 1},
23 | {6, 5, 4},
24 | {9, 8, 7},
25 | }
26 |
27 | for _, slice := range slices {
28 | wg.Add(1)
29 | go sortSlice(slice, &wg)
30 | }
31 |
32 | wg.Wait()
33 | fmt.Println("All slices sorted")
34 | }
35 |
--------------------------------------------------------------------------------
/027_panic_and_defer/005_panic_with_recover/005_panic_with_recover.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | func main() {
8 |
9 | // The recover function is used to regain control of a panicking goroutine.
10 | // It can be used within a deferred function to catch a panic and prevent the program from crashing
11 |
12 | defer func() {
13 | if r := recover(); r != nil {
14 | fmt.Println("Recovered from panic:", r)
15 | }
16 | }()
17 | fmt.Println("Starting main")
18 | panic("A severe error occurred")
19 | fmt.Println("This will not be printed")
20 |
21 | /*
22 |
23 | Starting main
24 | Recovered from panic: A severe error occurred
25 |
26 | */
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/030_json/005_custom_json_field_names/005_custom_json_field_names.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | )
7 |
8 | type Person5 struct {
9 | Name string `json:"full_name"`
10 | Age int `json:"age"`
11 | Country string `json:"country"`
12 | }
13 |
14 | func main() {
15 |
16 | // This example demonstrates how to customize JSON field names using struct tags (json:"field_name")
17 |
18 | person := Person5{
19 | Name: "John Doe",
20 | Age: 30,
21 | Country: "USA",
22 | }
23 |
24 | jsonData, err := json.Marshal(person)
25 | if err != nil {
26 | fmt.Println("Error encoding JSON:", err)
27 | return
28 | }
29 |
30 | fmt.Println(string(jsonData))
31 | }
32 |
--------------------------------------------------------------------------------
/020_timers/003_reset_timer/003_reset_timer.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | // Resetting a Timer
11 | // The Reset method is used to reset a timer to a new duration.
12 | // If the timer had already fired, it will restart with the new duration
13 |
14 | // Create a timer that will fire after 2 seconds
15 | timer := time.NewTimer(2 * time.Second)
16 |
17 | // Start a goroutine to reset the timer after 1 second
18 | go func() {
19 | time.Sleep(1 * time.Second)
20 | timer.Reset(4 * time.Second)
21 | fmt.Println("Timer reset to 4 seconds.")
22 | }()
23 |
24 | // Wait for the timer to fire
25 | <-timer.C
26 | fmt.Println("Timer fired!")
27 | }
28 |
--------------------------------------------------------------------------------
/024_rate_limiter/005_rate_limiter_with_time_newticker/005_rate_limiter_with_time_newticker.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | // Rate Limiting Using time.NewTicker
11 | // Use time.NewTicker for more control over the ticker's lifecycle
12 |
13 | requests := make(chan int, 5)
14 |
15 | for i := 1; i <= 5; i++ {
16 | requests <- i
17 | }
18 | close(requests)
19 |
20 | // Create a ticker that ticks every 200 milliseconds
21 | ticker := time.NewTicker(200 * time.Millisecond)
22 | defer ticker.Stop()
23 |
24 | for req := range requests {
25 | <-ticker.C // Wait for the next tick
26 | fmt.Println("Request", req, "processed at", time.Now())
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/026_sorting/004_sorting_by_multiple_fields/004_sorting_by_multiple_fields.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sort"
6 | )
7 |
8 | type Person1 struct {
9 | Name string
10 | Age int
11 | }
12 |
13 | func main() {
14 |
15 | // Demonstrate how to sort by multiple fields. First by Age, and if the Age is the same, then by Name
16 |
17 | people := []Person1{
18 | {"Alice", 30},
19 | {"Bob", 25},
20 | {"Charlie", 30},
21 | {"Dave", 25},
22 | }
23 |
24 | sort.Slice(people, func(i, j int) bool {
25 | if people[i].Age == people[j].Age {
26 | return people[i].Name < people[j].Name
27 | }
28 | return people[i].Age < people[j].Age
29 | })
30 |
31 | fmt.Println("Sorted by age and name:", people)
32 | }
33 |
--------------------------------------------------------------------------------
/018_closing_channel/05_panic_when_closing_an_already_closed_channel/05_panic_when_closing_an_already_closed_channel.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 |
7 | // Panic when Closing an Already Closed Channel
8 |
9 | // Closing an already closed channel will cause a panic.
10 | // In this example, the recover() function is used to handle the panic gracefully
11 |
12 | ch := make(chan int)
13 | close(ch) // Close the channel
14 |
15 | defer func() {
16 | if r := recover(); r != nil {
17 | fmt.Println("Recovered from panic:", r)
18 | }
19 | }()
20 |
21 | // Attempting to close an already closed channel will cause a panic
22 | close(ch)
23 |
24 | fmt.Println("This line will not be executed")
25 | }
26 |
--------------------------------------------------------------------------------
/025_atomic_counters/001_basic_atomic_counter_using_sync_atomic/001_basic_atomic_counter_using_sync_atomic.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | "sync/atomic"
7 | )
8 |
9 | func main() {
10 |
11 | // Basic Atomic Counter Using sync/atomic
12 | // use an atomic counter to increment and retrieve values safely across multiple goroutines
13 |
14 | var counter int32 // Shared counter variable
15 | var wg sync.WaitGroup
16 |
17 | for i := 0; i < 5; i++ {
18 | wg.Add(1)
19 | go func() {
20 | for j := 0; j < 1000; j++ {
21 | atomic.AddInt32(&counter, 1) // Atomically increment the counter
22 | }
23 | wg.Done()
24 | }()
25 | }
26 |
27 | wg.Wait()
28 | fmt.Println("Final Counter:", counter)
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/026_sorting/009_sorting_a_map_by_values/009_sorting_a_map_by_values.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sort"
6 | )
7 |
8 | func main() {
9 |
10 | // Show how to sort a map by its values
11 |
12 | ages := map[string]int{
13 | "Alice": 25,
14 | "Charlie": 20,
15 | "Bob": 30,
16 | }
17 |
18 | type kv struct {
19 | Key string
20 | Value int
21 | }
22 |
23 | var sortedAges []kv
24 | for k, v := range ages {
25 | sortedAges = append(sortedAges, kv{k, v})
26 | }
27 |
28 | sort.Slice(sortedAges, func(i, j int) bool {
29 | return sortedAges[i].Value < sortedAges[j].Value
30 | })
31 |
32 | fmt.Println("Sorted by values:")
33 | for _, kv := range sortedAges {
34 | fmt.Println(kv.Key, kv.Value)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/023_waitgroup/001_basic_waitgroup/001_basic_waitgroup.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | )
7 |
8 | func worker(id int, wg *sync.WaitGroup) {
9 | defer wg.Done()
10 | fmt.Printf("Worker %d starting\n", id)
11 | // Simulate some work with sleep
12 | // time.Sleep(time.Second)
13 | fmt.Printf("Worker %d done\n", id)
14 | }
15 |
16 | func main() {
17 |
18 | // we use a WaitGroup to wait for a set of goroutines to complete their execution before the program exits
19 |
20 | // Basic WaitGroup Example
21 |
22 | var wg sync.WaitGroup
23 |
24 | for i := 1; i <= 3; i++ {
25 | wg.Add(1)
26 | go worker(i, &wg)
27 | }
28 |
29 | // Wait for all workers to finish
30 | wg.Wait()
31 | fmt.Println("All workers completed.")
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/018_closing_channel/01_basic_channel_closing/01_basic_channel_closing.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 |
7 | // Basic Channel Closing
8 | // In this example, the channel is closed using close(ch) after all values are sent.
9 | // The range loop is used to receive values until the channel is closed.
10 | // Once the channel is closed, the loop automatically exits.
11 |
12 | ch := make(chan int)
13 |
14 | go func() {
15 | for i := 0; i < 5; i++ {
16 | ch <- i
17 | }
18 | close(ch) // Close the channel after sending all values
19 | }()
20 |
21 | // Receiving values until the channel is closed
22 | for value := range ch {
23 | fmt.Println("Received:", value)
24 | }
25 |
26 | fmt.Println("Channel closed, no more data.")
27 | }
28 |
--------------------------------------------------------------------------------
/021_tickers/01_basic_ticker/01_basic_ticker.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | // Tickers are used to perform an action at regular intervals for a specified duration.
11 | // A ticker can be created using the NewTicker function from the time package
12 |
13 | // Simple Ticker
14 | // create a ticker that ticks every 1 second
15 |
16 | // Create a ticker that ticks every 1 second
17 | ticker := time.NewTicker(1 * time.Second)
18 |
19 | // Stop the ticker after 5 ticks
20 | go func() {
21 | time.Sleep(5 * time.Second)
22 | ticker.Stop()
23 | }()
24 |
25 | // Print the tick events
26 | for t := range ticker.C {
27 | fmt.Println("Tick at", t)
28 | }
29 |
30 | fmt.Println("Ticker stopped.")
31 | }
32 |
--------------------------------------------------------------------------------
/020_timers/005_timer_with_select/005_timer_with_select.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | // Timer with Select ( Use select to handle timers alongside other concurrent events )
11 | // You can use timers within a select statement to wait for multiple events simultaneously,
12 | // including the timer firing
13 |
14 | timer1 := time.NewTimer(2 * time.Second) // create timer in 2 seconds
15 | timer2 := time.NewTimer(4 * time.Second) // create timer in 4 seconds
16 |
17 | select {
18 | case <-timer1.C:
19 | fmt.Println("Timer 1 fired")
20 | case <-timer2.C:
21 | fmt.Println("Timer 2 fired")
22 | case <-time.After(3 * time.Second):
23 | fmt.Println("Timeout! No timer fired in 3 seconds.")
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/026_sorting/005_sorting_a_custom_type_using_sort_interface/005_sorting_a_custom_type_using_sort_interface.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sort"
6 | )
7 |
8 | type Person2 struct {
9 | Name string
10 | Age int
11 | }
12 |
13 | type ByAge []Person2
14 |
15 | func (a ByAge) Len() int { return len(a) }
16 | func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
17 | func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
18 |
19 | func main() {
20 |
21 | // Show how to implement the sort.Interface to sort a custom type
22 |
23 | people := []Person2{
24 | {"Alice", 25},
25 | {"Bob", 30},
26 | {"Charlie", 20},
27 | }
28 |
29 | sort.Sort(ByAge(people))
30 | fmt.Println("Sorted by age using sort.Interface:", people)
31 | }
32 |
--------------------------------------------------------------------------------
/020_timers/002_stop_timer/002_stop_timer.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | // Stopping a Timer
11 | // You can stop a timer before it fires using the Stop method.
12 | //If the timer is stopped before it fires, the program will not receive any value from the timer's channel
13 |
14 | // Create a timer that will fire after 3 seconds
15 | timer := time.NewTimer(3 * time.Second)
16 |
17 | // Start a goroutine to stop the timer after 1 second
18 | go func() {
19 | time.Sleep(1 * time.Second)
20 | stop := timer.Stop()
21 | if stop {
22 | fmt.Println("Timer stopped before it fired.")
23 | }
24 | }()
25 |
26 | // Wait for the timer to fire
27 | <-timer.C
28 | fmt.Println("This will not be printed if the timer is stopped.")
29 | }
30 |
--------------------------------------------------------------------------------
/018_closing_channel/04_sending_a_signal_with_a_closed_channel/04_sending_a_signal_with_a_closed_channel.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func task(ch chan bool) {
9 | time.Sleep(2 * time.Second)
10 | close(ch) // Close the channel to send a signal
11 | }
12 |
13 | func main() {
14 |
15 | // Sending a Signal with a Closed Channel
16 |
17 | // a channel is used as a signal. The task goroutine performs some work and then closes the channel to signal that the task is complete.
18 | // The main function waits for the signal by reading from the channel
19 |
20 | signal := make(chan bool)
21 |
22 | go task(signal)
23 |
24 | fmt.Println("Waiting for task to complete...")
25 |
26 | // Wait for the signal
27 | <-signal
28 |
29 | fmt.Println("Task completed.")
30 | }
31 |
--------------------------------------------------------------------------------
/019_range_over_channel/001_basic_example_range_over_channel/001_basic_example_range_over_channel.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | func main() {
8 |
9 | // Basic Example: Range Over a Channel
10 | // a single goroutine sends a series of integers to a channel,
11 | // and the main goroutine iterates over these values using range
12 |
13 | ch := make(chan int)
14 |
15 | // Start a goroutine that sends values to the channel
16 | go func() {
17 | for i := 0; i < 5; i++ {
18 | ch <- i
19 | }
20 | close(ch) // Close the channel after sending all values
21 | }()
22 |
23 | // Use range to receive values from the channel until it's closed
24 | for value := range ch {
25 | fmt.Println("Received:", value)
26 | }
27 |
28 | fmt.Println("Channel closed, no more data.")
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/018_closing_channel/02_detecting_closed_channel/02_detecting_closed_channel.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 |
7 | // Detecting Closed Channel
8 |
9 | // value, ok := <-ch is used to check if the channel is closed.
10 | // The ok will be false when the channel is closed, and the loop break
11 |
12 | ch := make(chan int)
13 | done := make(chan bool)
14 |
15 | go func() {
16 | for i := 0; i < 5; i++ {
17 | ch <- i
18 | }
19 | close(ch) // Close the channel after sending all values
20 | done <- true
21 | }()
22 |
23 | // Continuously receive until done is true
24 | for {
25 | value, ok := <-ch
26 | if !ok {
27 | fmt.Println("Channel is closed.")
28 | break
29 | }
30 | fmt.Println("Received:", value)
31 | }
32 | <-done // Ensure the goroutine has finished
33 | }
34 |
--------------------------------------------------------------------------------
/021_tickers/05_ticker_with_limited_ticks/05_ticker_with_limited_ticks.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | // Ticker with Limited Ticks
11 | // Stop the ticker after a certain number of ticks
12 |
13 | // Create a ticker that ticks every 1 second
14 | ticker := time.NewTicker(1 * time.Second)
15 |
16 | // Create a counter for the number of ticks
17 | count := 0
18 | maxTicks := 5
19 |
20 | for t := range ticker.C {
21 | fmt.Println("Tick at", t)
22 | count++
23 | if count >= maxTicks {
24 | ticker.Stop()
25 | break
26 | }
27 | }
28 |
29 | fmt.Println("Ticker stopped after", maxTicks, "ticks.")
30 |
31 | // The ticker is set to stop after 5 ticks
32 | // The loop counts the ticks and stops the ticker once the limit is reached
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/021_tickers/03_ticker_with_select/03_ticker_with_select.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | // Using Ticker with Select
11 | // Use a ticker inside a select statement to manage multiple concurrent events
12 |
13 | ticker := time.NewTicker(1 * time.Second)
14 | stop := make(chan bool)
15 |
16 | go func() {
17 | time.Sleep(3 * time.Second)
18 | stop <- true
19 | }()
20 |
21 | for {
22 | select {
23 | case t := <-ticker.C:
24 | fmt.Println("Tick at", t)
25 | case <-stop:
26 | fmt.Println("Stop signal received.")
27 | ticker.Stop()
28 | return
29 | }
30 | }
31 |
32 | // The select statement listens for ticks and a stop signal
33 | // When the stop channel receives a signal, the ticker is stopped, and the program exits the loop
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/021_tickers/02_stop_ticker/02_stop_ticker.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | // Stopping a Ticker
11 | // Stopping a ticker is crucial when you no longer need it to avoid unnecessary resource consumption
12 |
13 | // Create a ticker that ticks every 500 milliseconds
14 | ticker := time.NewTicker(500 * time.Millisecond)
15 |
16 | // Create a channel to signal the stop of the ticker
17 | done := make(chan bool)
18 |
19 | go func() {
20 | time.Sleep(2 * time.Second) // Let the ticker run for 2 seconds
21 | ticker.Stop()
22 | done <- true
23 | }()
24 |
25 | // Print tick events until the ticker is stopped
26 | go func() {
27 | for t := range ticker.C {
28 | fmt.Println("Tick at", t)
29 | }
30 | }()
31 |
32 | <-done
33 | fmt.Println("Ticker stopped.")
34 | }
35 |
--------------------------------------------------------------------------------
/029_text_samples/005_template_with_data_formatting/005_template_with_data_formatting.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "text/template"
7 | "time"
8 | )
9 |
10 | type Event struct {
11 | Name string
12 | Date time.Time
13 | }
14 |
15 | func main() {
16 |
17 | // This template formats a time.Time field in a specific way using Go's date formatting.
18 | // The format string "Monday, January 2, 2006" is a standard Go way of specifying date formats
19 |
20 | tpl := `Event: {{.Name}}
21 | Date: {{.Date.Format "Monday, January 2, 2006"}}`
22 |
23 | t := template.Must(template.New("event").Parse(tpl))
24 |
25 | event := Event{
26 | Name: "Go Conference",
27 | Date: time.Now(),
28 | }
29 |
30 | err := t.Execute(os.Stdout, event)
31 | if err != nil {
32 | fmt.Println("Error executing template:", err)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/030_json/002_basic_decoding_json/002_basic_decoding_json.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | )
7 |
8 | type Person1 struct {
9 | Name string
10 | Age int
11 | Country string
12 | }
13 |
14 | func main() {
15 |
16 | // This example demonstrates how to convert a JSON string into a Go struct using json.Unmarshal
17 |
18 | jsonString := `{"Name":"John","Age":30,"Country":"USA"}`
19 |
20 | var person Person1
21 |
22 | err := json.Unmarshal([]byte(jsonString), &person)
23 | if err != nil {
24 | fmt.Println("Error decoding JSON:", err)
25 | return
26 | }
27 |
28 | // Marshal the struct back to JSON format
29 | jsonOutput, err := json.MarshalIndent(person, "", " ")
30 | if err != nil {
31 | fmt.Println("Error encoding JSON:", err)
32 | return
33 | }
34 |
35 | fmt.Println(string(jsonOutput))
36 | }
37 |
--------------------------------------------------------------------------------
/030_json/010_streaming_json_encoding/010_streaming_json_encoding.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "os"
7 | )
8 |
9 | type Person10 struct {
10 | Name string
11 | Age int
12 | Country string
13 | }
14 |
15 | func main() {
16 |
17 | people := []Person10{
18 | {"John", 30, "USA"},
19 | {"Alice", 28, "Canada"},
20 | {"Bob", 25, "UK"},
21 | }
22 |
23 | // Create a new JSON encoder that writes to standard output
24 | encoder := json.NewEncoder(os.Stdout)
25 |
26 | // Optionally set the encoder to use indentation for better readability
27 | encoder.SetIndent("", " ")
28 |
29 | // Encode each person individually
30 | for _, person := range people {
31 | err := encoder.Encode(person)
32 | if err != nil {
33 | fmt.Println("Error encoding JSON:", err)
34 | return
35 | }
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/030_json/008_decoding_json_into_a_map_string_interface/008_decoding_json_into_a_map_string_interface.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | )
7 |
8 | func main() {
9 |
10 | // This example demonstrates how to decode JSON data into a map[string]interface{}.
11 | // This is useful for working with JSON data when the structure isn't known in advance
12 |
13 | jsonString := `{"Name":"John","Age":30,"Country":"USA"}`
14 |
15 | var result map[string]interface{}
16 |
17 | err := json.Unmarshal([]byte(jsonString), &result)
18 | if err != nil {
19 | fmt.Println("Error decoding JSON into map:", err)
20 | return
21 | }
22 |
23 | fmt.Println("Decoded map:", result)
24 |
25 | // Accessing fields
26 | fmt.Println("Name:", result["Name"])
27 | fmt.Println("Age:", result["Age"])
28 | fmt.Println("Country:", result["Country"])
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/025_atomic_counters/003_atomic_flag_using_sync_atomic/003_atomic_flag_using_sync_atomic.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | "sync/atomic"
7 | )
8 |
9 | func main() {
10 |
11 | // Atomic Flag Example Using sync/atomic
12 | // Demonstrate using an atomic boolean flag to control access to a critical section
13 |
14 | var flag int32 // Shared atomic flag
15 | var wg sync.WaitGroup
16 |
17 | for i := 0; i < 5; i++ {
18 | wg.Add(1)
19 | go func(id int) {
20 | defer wg.Done()
21 |
22 | if atomic.CompareAndSwapInt32(&flag, 0, 1) { // Try to set flag to 1
23 | fmt.Printf("Goroutine %d entered critical section\n", id)
24 | atomic.StoreInt32(&flag, 0) // Reset flag to 0
25 | } else {
26 | fmt.Printf("Goroutine %d did not enter critical section\n", id)
27 | }
28 | }(i)
29 | }
30 |
31 | wg.Wait()
32 | fmt.Println("All goroutines done.")
33 | }
34 |
--------------------------------------------------------------------------------
/030_json/004_working_with_json_arrays/004_working_with_json_arrays.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | )
7 |
8 | type Person4 struct {
9 | Name string
10 | Age int
11 | Country string
12 | }
13 |
14 | func main() {
15 |
16 | // This example shows how to decode a JSON array into a slice of structs
17 |
18 | jsonString := `[{"Name":"John","Age":30,"Country":"USA"},{"Name":"Alice","Age":28,"Country":"Canada"}]`
19 |
20 | var people []Person4
21 |
22 | err := json.Unmarshal([]byte(jsonString), &people)
23 | if err != nil {
24 | fmt.Println("Error decoding JSON array:", err)
25 | return
26 | }
27 |
28 | // Marshal the struct back to JSON format
29 | jsonOutput, err := json.MarshalIndent(people, "", " ")
30 | if err != nil {
31 | fmt.Println("Error encoding JSON:", err)
32 | return
33 | }
34 |
35 | fmt.Println(string(jsonOutput))
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 | *.test
8 | *.out
9 |
10 | # Output of the 'go build' and 'go run' commands
11 | /build
12 | bin/
13 | *.log
14 |
15 | # Testing and Coverage files
16 | *.coverprofile
17 | *.test
18 |
19 | # Go workspace file
20 | go.work
21 |
22 | # Dependency directories (vendor/)
23 | vendor/
24 |
25 | # Go module files
26 | go.sum
27 |
28 | # Temporary files
29 | *.tmp
30 | *.temp
31 |
32 | # IDE files
33 | # JetBrains IDEs (e.g., GoLand)
34 | .idea/
35 | *.iml
36 |
37 | # VS Code
38 | .vscode/
39 | *.code-workspace
40 |
41 | # macOS files
42 | .DS_Store
43 |
44 | # Linux Files
45 | *~
46 |
47 | # Node.js files (if you use it in some submodules or CI/CD pipeline)
48 | node_modules/
49 |
50 | # Go environment files
51 | .env
52 |
53 | # Logs
54 | *.log
55 |
56 | # Coverage files
57 | coverage.out
58 | coverage.html
59 |
--------------------------------------------------------------------------------
/029_text_samples/002_loops_in_templates/002_loops_in_templates.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "text/template"
7 | )
8 |
9 | type Task struct {
10 | Title string
11 | Status string
12 | }
13 |
14 | type Person1 struct {
15 | Name string
16 | Tasks []Task
17 | }
18 |
19 | func main() {
20 |
21 | // This template uses range to loop over a slice of Task structs and list out each task with its status.
22 |
23 | person := Person1{
24 | Name: "Bob",
25 | Tasks: []Task{
26 | {"Task 1", "Completed"},
27 | {"Task 2", "Pending"},
28 | {"Task 3", "In Progress"},
29 | },
30 | }
31 |
32 | tpl := `{{.Name}}'s Tasks:
33 | {{range .Tasks}}- {{.Title}}: {{.Status}}
34 | {{end}}`
35 |
36 | t := template.Must(template.New("person").Parse(tpl))
37 |
38 | err := t.Execute(os.Stdout, person)
39 | if err != nil {
40 | fmt.Println("Error executing template:", err)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/029_text_samples/001_conditional_logic_in_templates/001_conditional_logic_in_templates.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "text/template"
7 | )
8 |
9 | type Person struct {
10 | Name string
11 | Age int
12 | Country string
13 | }
14 |
15 | func main() {
16 |
17 | // This template includes a conditional if block to check whether the Age field is present.
18 | // If it's not, an alternate message is shown
19 |
20 | person := Person{
21 | Name: "Alice",
22 | Age: 25,
23 | Country: "Canada",
24 | }
25 |
26 | tpl := `{{if .Age}}My name is {{.Name}} and I am {{.Age}} years old.{{else}}My name is {{.Name}} and I prefer not to disclose my age.{{end}}
27 | I live in {{.Country}}.`
28 |
29 | t := template.Must(template.New("person").Parse(tpl))
30 |
31 | err := t.Execute(os.Stdout, person)
32 | if err != nil {
33 | fmt.Println("Error executing template:", err)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/021_tickers/04_reset_ticker/04_reset_ticker.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | // Resetting a Ticker
11 | // Resetting a ticker allows you to change the ticker's interval dynamically
12 |
13 | // Create a ticker that ticks every 1 second
14 | ticker := time.NewTicker(1 * time.Second)
15 |
16 | go func() {
17 | for t := range ticker.C {
18 | fmt.Println("Tick at", t)
19 | }
20 | }()
21 |
22 | time.Sleep(3 * time.Second)
23 |
24 | // Reset the ticker to tick every 2 seconds instead of 1 second
25 | ticker.Reset(2 * time.Second)
26 |
27 | time.Sleep(6 * time.Second)
28 | ticker.Stop()
29 | fmt.Println("Ticker stopped.")
30 |
31 | // The ticker initially ticks every 1 second.
32 | // After 3 seconds, ticker.Reset(2 * time.Second) changes the interval to 2 seconds
33 | // The ticker continues ticking at the new interval until it is stopped
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/024_rate_limiter/004_rate_limiter_with_context/004_rate_limiter_with_context.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "time"
7 | )
8 |
9 | func processRequest(ctx context.Context, req int) {
10 | select {
11 | case <-ctx.Done():
12 | fmt.Println("Request", req, "cancelled at", time.Now())
13 | case <-time.After(200 * time.Millisecond):
14 | fmt.Println("Request", req, "processed at", time.Now())
15 | }
16 | }
17 |
18 | func main() {
19 |
20 | // Rate Limiting with context.Context
21 | // Use context.Context to implement rate limiting, which allows for more control over request cancellation
22 |
23 | requests := make(chan int, 5)
24 |
25 | for i := 1; i <= 5; i++ {
26 | requests <- i
27 | }
28 | close(requests)
29 |
30 | for req := range requests {
31 | ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
32 | processRequest(ctx, req)
33 | cancel()
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/023_waitgroup/004_waitgroup_with_error_handling/004_waitgroup_with_error_handling.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | )
7 |
8 | func worker1(id int, wg *sync.WaitGroup, errors chan error) {
9 | defer wg.Done()
10 |
11 | // Simulate an error for worker 2
12 | if id == 2 {
13 | errors <- fmt.Errorf("worker %d encountered an error", id)
14 | return
15 | }
16 |
17 | fmt.Printf("Worker %d completed successfully\n", id)
18 | }
19 |
20 | func main() {
21 |
22 | // WaitGroup with Error Handling
23 | // we demonstrate using a WaitGroup with error handling in the workers
24 |
25 | var wg sync.WaitGroup
26 | errors := make(chan error, 3)
27 |
28 | for i := 1; i <= 3; i++ {
29 | wg.Add(1)
30 | go worker1(i, &wg, errors)
31 | }
32 |
33 | // Wait for all workers to finish
34 | wg.Wait()
35 | close(errors)
36 |
37 | // Check for errors
38 | for err := range errors {
39 | if err != nil {
40 | fmt.Println("Error:", err)
41 | }
42 | }
43 |
44 | fmt.Println("All workers completed.")
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/029_text_samples/003_template_functions/003_template_functions.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "strings"
7 | "text/template"
8 | )
9 |
10 | type Person2 struct {
11 | Name string
12 | Age int
13 | Country string
14 | }
15 |
16 | func main() {
17 |
18 | // This example demonstrates how to use custom template functions.
19 | // The FuncMap is used to register functions like strings.ToUpper and strings.ToLower, which are then used in the template.
20 |
21 | funcMap := template.FuncMap{
22 | "ToUpper": strings.ToUpper,
23 | "ToLower": strings.ToLower,
24 | }
25 |
26 | tpl := `Name (upper): {{.Name | ToUpper}}
27 | Name (lower): {{.Name | ToLower}}
28 | Country: {{.Country}}`
29 |
30 | t := template.Must(template.New("person").Funcs(funcMap).Parse(tpl))
31 |
32 | person := Person2{
33 | Name: "Charlie",
34 | Age: 28,
35 | Country: "UK",
36 | }
37 |
38 | err := t.Execute(os.Stdout, person)
39 | if err != nil {
40 | fmt.Println("Error executing template:", err)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/030_json/003_handling_nested_json_structures/003_handling_nested_json_structures.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | )
7 |
8 | type Address struct {
9 | City string
10 | State string
11 | Country string
12 | }
13 |
14 | type Person3 struct {
15 | Name string
16 | Age int
17 | Address Address
18 | }
19 |
20 | func main() {
21 |
22 | // This example illustrates how to handle nested JSON objects by defining structs within structs.
23 |
24 | jsonString := `{"Name":"Alice","Age":28,"Address":{"City":"Los Angeles","State":"CA","Country":"USA"}}`
25 |
26 | var person Person3
27 |
28 | err := json.Unmarshal([]byte(jsonString), &person)
29 | if err != nil {
30 | fmt.Println("Error decoding JSON:", err)
31 | return
32 | }
33 |
34 | // Marshal the struct back to JSON format
35 | jsonOutput, err := json.MarshalIndent(person, "", " ")
36 | if err != nil {
37 | fmt.Println("Error encoding JSON:", err)
38 | return
39 | }
40 |
41 | fmt.Println(string(jsonOutput))
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/029_text_samples/004_nested_templates/004_nested_templates.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "text/template"
7 | )
8 |
9 | type Address struct {
10 | City string
11 | Country string
12 | }
13 |
14 | type Person4 struct {
15 | Name string
16 | Age int
17 | Address Address
18 | }
19 |
20 | func main() {
21 |
22 | // This example shows how to define and use nested templates within a larger template.
23 | // The address template is defined and then included using the template keyword
24 |
25 | tpl := `{{define "address"}}{{.City}}, {{.Country}}{{end}}
26 |
27 | Name: {{.Name}}
28 | Age: {{.Age}}
29 | Address: {{template "address" .Address}}`
30 |
31 | t := template.Must(template.New("person").Parse(tpl))
32 |
33 | person := Person4{
34 | Name: "Dave",
35 | Age: 40,
36 | Address: Address{
37 | City: "Berlin",
38 | Country: "Germany",
39 | },
40 | }
41 |
42 | err := t.Execute(os.Stdout, person)
43 | if err != nil {
44 | fmt.Println("Error executing template:", err)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/019_range_over_channel/002_multiple_goroutines_sending_to_a_channel/002_multiple_goroutines_sending_to_a_channel.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | )
7 |
8 | func worker(id int, ch chan int, wg *sync.WaitGroup) {
9 | defer wg.Done()
10 | for i := 0; i < 3; i++ {
11 | ch <- id*10 + i
12 | }
13 | }
14 |
15 | func main() {
16 |
17 | // Multiple Goroutines Sending to a Channel
18 | // we'll have multiple goroutines sending values to the same channel.
19 | // The range will receive all these values until the channel is closed
20 |
21 | ch := make(chan int)
22 | var wg sync.WaitGroup
23 |
24 | // Start 3 worker goroutines
25 | for i := 1; i <= 3; i++ {
26 | wg.Add(1)
27 | go worker(i, ch, &wg)
28 | }
29 |
30 | // Close the channel once all workers are done
31 | go func() {
32 | wg.Wait()
33 | close(ch)
34 | }()
35 |
36 | // Receive and print values from the channel until it's closed
37 | for value := range ch {
38 | fmt.Println("Received:", value)
39 | }
40 |
41 | fmt.Println("All workers done, channel closed.")
42 | }
43 |
--------------------------------------------------------------------------------
/029_text_samples/006_complex_structs_and_template_actions/006_complex_structs_and_template_actions.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "text/template"
7 | )
8 |
9 | type Contact struct {
10 | Phone string
11 | Email string
12 | }
13 |
14 | type Person6 struct {
15 | Name string
16 | Age int
17 | Contact Contact
18 | }
19 |
20 | func main() {
21 |
22 | // The with action is used here to focus the template on a specific field (Contact) of the Person struct,
23 | // making it easier to work with deeply nested data
24 |
25 | tpl := `Name: {{.Name}}
26 | Age: {{.Age}}
27 | Contact Info:
28 | {{with .Contact}}
29 | Phone: {{.Phone}}
30 | Email: {{.Email}}
31 | {{end}}`
32 |
33 | t := template.Must(template.New("person").Parse(tpl))
34 |
35 | person := Person6{
36 | Name: "Eva",
37 | Age: 32,
38 | Contact: Contact{
39 | Phone: "123-456-7890",
40 | Email: "eva@example.com",
41 | },
42 | }
43 |
44 | err := t.Execute(os.Stdout, person)
45 | if err != nil {
46 | fmt.Println("Error executing template:", err)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/024_rate_limiter/002_rate_limiter_burst_capacity/002_rate_limiter_burst_capacity.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func main() {
9 |
10 | // Rate Limiting with a Burst Capacity
11 | // Demonstrate how to allow a burst of requests before enforcing the rate limit
12 |
13 | requests := make(chan int, 5)
14 |
15 | for i := 1; i <= 5; i++ {
16 | requests <- i
17 | }
18 | close(requests)
19 |
20 | // Create a buffered channel to allow a burst of up to 3 requests
21 | burstLimiter := make(chan time.Time, 3)
22 |
23 | // Initially fill the burstLimiter channel to allow immediate processing of up to 3 requests
24 | for i := 0; i < 3; i++ {
25 | burstLimiter <- time.Now()
26 | }
27 |
28 | // Fill the burstLimiter channel every 200 milliseconds to maintain the rate limit
29 | go func() {
30 | for t := range time.Tick(200 * time.Millisecond) {
31 | burstLimiter <- t
32 | }
33 | }()
34 |
35 | for req := range requests {
36 | <-burstLimiter // Wait for a token from burstLimiter
37 | fmt.Println("Request", req, "processed at", time.Now())
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/025_atomic_counters/004_atomic_counter_with_load_and_store_operations/004_atomic_counter_with_load_and_store_operations.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | "sync/atomic"
7 | )
8 |
9 | func main() {
10 |
11 | // Atomic Counter with Load and Store Operations
12 | // Illustrate using atomic load and store operations to ensure safe reading and updating of a counter
13 |
14 | var counter int64 // Shared atomic counter
15 | var wg sync.WaitGroup
16 |
17 | // Increment counter in goroutines
18 | for i := 0; i < 5; i++ {
19 | wg.Add(1)
20 | go func() {
21 | for j := 0; j < 1000; j++ {
22 | atomic.AddInt64(&counter, 1)
23 | }
24 | wg.Done()
25 | }()
26 | }
27 |
28 | // Load and store operations
29 | wg.Add(1)
30 | go func() {
31 | defer wg.Done()
32 | current := atomic.LoadInt64(&counter) // Atomically load the counter value
33 | fmt.Println("Current Counter:", current)
34 | atomic.StoreInt64(&counter, current+1000) // Atomically set counter to current + 1000
35 | fmt.Println("Updated Counter:", atomic.LoadInt64(&counter))
36 | }()
37 |
38 | wg.Wait()
39 | fmt.Println("Final Counter:", counter)
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/025_atomic_counters/002_ atomic_counter _with_decrement_and_compare_and_swap/002_ atomic_counter _with_decrement_and_compare_and_swap.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | "sync/atomic"
7 | )
8 |
9 | func main() {
10 |
11 | // Atomic Counter with Decrement and Compare-And-Swap (CAS)
12 | // use atomic operations to increment, decrement, and use the compare-and-swap operation
13 |
14 | var counter int32 = 100 // Initialize counter
15 | var wg sync.WaitGroup
16 |
17 | // Increment goroutine
18 | wg.Add(1)
19 | go func() {
20 | atomic.AddInt32(&counter, 1) // Increment counter
21 | wg.Done()
22 | }()
23 |
24 | // Decrement goroutine
25 | wg.Add(1)
26 | go func() {
27 | atomic.AddInt32(&counter, -1) // Decrement counter
28 | wg.Done()
29 | }()
30 |
31 | // Compare-And-Swap goroutine
32 | wg.Add(1)
33 | go func() {
34 | // CAS: If counter equals 100, set it to 200
35 | if atomic.CompareAndSwapInt32(&counter, 100, 200) {
36 | fmt.Println("CAS successful, new value:", counter)
37 | } else {
38 | fmt.Println("CAS failed, current value:", counter)
39 | }
40 | wg.Done()
41 | }()
42 |
43 | wg.Wait()
44 | fmt.Println("Final Counter:", counter)
45 | }
46 |
--------------------------------------------------------------------------------
/022_worker_pools/002_worker_pool_with_buffered_channels/002_worker_pool_with_buffered_channels.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | )
7 |
8 | func bufferedWorker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
9 | defer wg.Done()
10 | for j := range jobs {
11 | fmt.Printf("Worker %d started job %d\n", id, j)
12 | results <- j * 2
13 | fmt.Printf("Worker %d finished job %d\n", id, j)
14 | }
15 | }
16 |
17 | func main() {
18 |
19 | // Worker Pool with Buffered Channels
20 | // How to use buffered channels to improve performance by reducing blocking when sending jobs to workers
21 |
22 | const numJobs = 5
23 | jobs := make(chan int, numJobs)
24 | results := make(chan int, numJobs)
25 |
26 | var wg sync.WaitGroup
27 |
28 | // Start workers
29 | for w := 1; w <= 3; w++ {
30 | wg.Add(1)
31 | go bufferedWorker(w, jobs, results, &wg)
32 | }
33 |
34 | // Send jobs to workers
35 | for j := 1; j <= numJobs; j++ {
36 | jobs <- j
37 | }
38 | close(jobs)
39 |
40 | // Wait for all workers to finish
41 | wg.Wait()
42 | close(results)
43 |
44 | // Collect results
45 | for result := range results {
46 | fmt.Println("Result:", result)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/023_waitgroup/003_waitgroup_with_multiple_waits/003_waitgroup_with_multiple_waits.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | "time"
7 | )
8 |
9 | func stageOne(id int, wg *sync.WaitGroup) {
10 | defer wg.Done()
11 | fmt.Printf("Stage one: Worker %d starting\n", id)
12 | time.Sleep(1 * time.Second)
13 | fmt.Printf("Stage one: Worker %d done\n", id)
14 | }
15 |
16 | func stageTwo(id int, wg *sync.WaitGroup) {
17 | defer wg.Done()
18 | fmt.Printf("Stage two: Worker %d starting\n", id)
19 | time.Sleep(1 * time.Second)
20 | fmt.Printf("Stage two: Worker %d done\n", id)
21 | }
22 |
23 | func main() {
24 |
25 | // WaitGroup with Multiple Waits
26 | // we use a WaitGroup to wait for different sets of goroutines at different stages of execution.
27 |
28 | var wg sync.WaitGroup
29 |
30 | // Stage one
31 | for i := 1; i <= 3; i++ {
32 | wg.Add(1)
33 | go stageOne(i, &wg)
34 | }
35 | wg.Wait() // Wait for all workers in stage one to complete
36 | fmt.Println("Stage one completed.")
37 |
38 | // Stage two
39 | for i := 1; i <= 3; i++ {
40 | wg.Add(1)
41 | go stageTwo(i, &wg)
42 | }
43 | wg.Wait() // Wait for all workers in stage two to complete
44 | fmt.Println("Stage two completed.")
45 | }
46 |
--------------------------------------------------------------------------------
/022_worker_pools/001_basic_worker_pool/001_basic_worker_pool.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | "time"
7 | )
8 |
9 | // Worker function to process jobs
10 | func worker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
11 | defer wg.Done()
12 | for j := range jobs {
13 | fmt.Printf("Worker %d processing job %d\n", id, j)
14 | time.Sleep(time.Second) // Simulate work
15 | results <- j * 2
16 | }
17 | }
18 |
19 | func main() {
20 |
21 | // In Go, worker pools are groups of workers dedicated to processing tasks.
22 | // Jobs are sent to a channel and handled by these workers, allowing tasks to be distributed and workload balanced efficiently
23 |
24 | // Basic Worker Pool
25 | // Basic worker pool where multiple workers process tasks from a shared channel.
26 |
27 | const numJobs = 5
28 | jobs := make(chan int, numJobs)
29 | results := make(chan int, numJobs)
30 |
31 | var wg sync.WaitGroup
32 |
33 | // Start workers
34 | for w := 1; w <= 3; w++ {
35 | wg.Add(1)
36 | go worker(w, jobs, results, &wg)
37 | }
38 |
39 | // Send jobs to workers
40 | for j := 1; j <= numJobs; j++ {
41 | jobs <- j
42 | }
43 | close(jobs)
44 |
45 | // Wait for all workers to finish
46 | wg.Wait()
47 | close(results)
48 |
49 | // Collect results
50 | for result := range results {
51 | fmt.Println("Result:", result)
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/001_hello_world/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Hello World
2 |
3 | This repository contains a simple Go (Golang) program that prints "Merhaba Dünya!" (Hello World!) to the console. It serves as an introductory example for Go, showcasing basic syntax and the use of the `fmt` package for output.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This is the most basic Go program to demonstrate how to print output using the `fmt` package.
9 | - It introduces Go's structure, including the `package main` declaration and the `main` function as the entry point of the program.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```golang
15 | package main
16 |
17 | import "fmt"
18 |
19 | func main() {
20 | fmt.Println("Merhaba Dünya!") // Outputs: Merhaba Dünya!
21 | }
22 | ```
23 |
24 | ### 🏃 How to Run
25 |
26 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
27 | 2. Clone this repository:
28 | ```bash
29 | git clone https://github.com/Rapter1990/go_sample_examples.git
30 | ```
31 | 3. Navigate to the `001_hello_world` directory:
32 | ```bash
33 | cd go_sample_examples/001_hello_world
34 | ```
35 | 4. Run the Go program:
36 | ```bash
37 | go run main.go
38 | ```
39 |
40 | ### 📦 Output
41 |
42 | When you run the program, you should see the following output:
43 |
44 | ```
45 | Merhaba Dünya!
46 | ```
47 |
--------------------------------------------------------------------------------
/030_json/009_decoding_json_with_unknown_fields/009_decoding_json_with_unknown_fields.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | )
7 |
8 | type Person9 struct {
9 | Name string
10 | Age int
11 | Country string
12 | Extra map[string]interface{} `json:"-"`
13 | }
14 |
15 | func (p *Person9) UnmarshalJSON(data []byte) error {
16 | type Alias Person9
17 | aux := &struct {
18 | *Alias
19 | }{
20 | Alias: (*Alias)(p),
21 | }
22 |
23 | if err := json.Unmarshal(data, &aux); err != nil {
24 | return err
25 | }
26 |
27 | // Unmarshal the remaining fields into the Extra map
28 | if err := json.Unmarshal(data, &p.Extra); err != nil {
29 | return err
30 | }
31 | delete(p.Extra, "Name")
32 | delete(p.Extra, "Age")
33 | delete(p.Extra, "Country")
34 |
35 | return nil
36 | }
37 |
38 | func main() {
39 |
40 | // This example shows how to decode JSON into a struct while capturing any additional unknown fields into a map.
41 | // The UnmarshalJSON method is overridden to achieve this
42 |
43 | jsonString := `{"Name":"John","Age":30,"Country":"USA","Nickname":"Johnny","Hobby":"Golf"}`
44 |
45 | var person Person9
46 | err := json.Unmarshal([]byte(jsonString), &person)
47 | if err != nil {
48 | fmt.Println("Error decoding JSON:", err)
49 | return
50 | }
51 |
52 | fmt.Printf("Decoded Struct with Extra Fields: %+v\n", person)
53 | fmt.Printf("Extra Fields: %+v\n", person.Extra)
54 | }
55 |
--------------------------------------------------------------------------------
/022_worker_pools/004_dynamic_worker_pool/004_dynamic_worker_pool.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | "time"
7 | )
8 |
9 | func dynamicWorker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
10 | defer wg.Done()
11 | for j := range jobs {
12 | fmt.Printf("Worker %d processing job %d\n", id, j)
13 | time.Sleep(time.Second) // Simulate work
14 | results <- j * 2
15 | }
16 | }
17 |
18 | func main() {
19 |
20 | // Dynamic Worker Pool
21 | // the number of workers can be adjusted dynamically based on the workload
22 |
23 | const numJobs = 10
24 | jobs := make(chan int, numJobs)
25 | results := make(chan int, numJobs)
26 |
27 | var wg sync.WaitGroup
28 |
29 | numWorkers := 3
30 |
31 | // Start workers
32 | for w := 1; w <= numWorkers; w++ {
33 | wg.Add(1)
34 | go dynamicWorker(w, jobs, results, &wg)
35 | }
36 |
37 | // Adjust number of workers based on workload
38 | go func() {
39 | time.Sleep(2 * time.Second)
40 | fmt.Println("Increasing number of workers...")
41 | for w := numWorkers + 1; w <= numWorkers+2; w++ {
42 | wg.Add(1)
43 | go dynamicWorker(w, jobs, results, &wg)
44 | }
45 | }()
46 |
47 | // Send jobs to workers
48 | for j := 1; j <= numJobs; j++ {
49 | jobs <- j
50 | }
51 | close(jobs)
52 |
53 | // Wait for all workers to finish
54 | wg.Wait()
55 | close(results)
56 |
57 | // Collect results
58 | for result := range results {
59 | fmt.Println("Result:", result)
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/022_worker_pools/003_worker_pool_with_error_handling/003_worker_pool_with_error_handling.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | )
7 |
8 | type Job struct {
9 | ID int
10 | Error error
11 | }
12 |
13 | func workerWithErrorHandling(id int, jobs <-chan Job, results chan<- Job, wg *sync.WaitGroup) {
14 | defer wg.Done()
15 | for j := range jobs {
16 | fmt.Printf("Worker %d processing job %d\n", id, j.ID)
17 | // Simulate error handling
18 | if j.ID%2 == 0 {
19 | j.Error = fmt.Errorf("error processing job %d", j.ID)
20 | }
21 | results <- j
22 | }
23 | }
24 |
25 | func main() {
26 |
27 | // Worker Pool with Error Handling
28 | // workers can report errors, and the main function can handle them
29 |
30 | const numJobs = 5
31 | jobs := make(chan Job, numJobs)
32 | results := make(chan Job, numJobs)
33 |
34 | var wg sync.WaitGroup
35 |
36 | // Start workers
37 | for w := 1; w <= 3; w++ {
38 | wg.Add(1)
39 | go workerWithErrorHandling(w, jobs, results, &wg)
40 | }
41 |
42 | // Send jobs to workers
43 | for j := 1; j <= numJobs; j++ {
44 | jobs <- Job{ID: j}
45 | }
46 | close(jobs)
47 |
48 | // Wait for all workers to finish
49 | wg.Wait()
50 | close(results)
51 |
52 | // Collect results
53 | for result := range results {
54 | if result.Error != nil {
55 | fmt.Printf("Job %d failed with error: %v\n", result.ID, result.Error)
56 | } else {
57 | fmt.Printf("Job %d completed successfully\n", result.ID)
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/026_sorting/001_basic_sorting_with_integers/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Basic Sorting with Integers
2 |
3 | This repository demonstrates how to sort a slice of integers in Go using the built-in `sort` package. It provides a basic example of how to work with sorting functionality in Go.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers sorting a slice of integers in ascending order using the `sort.Ints` function.
9 | - Sorting is an essential task in programming, and Go provides convenient tools for it in the `sort` package.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```golang
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "sort"
20 | )
21 |
22 | func main() {
23 | // Slice of integers to sort
24 | numbers := []int{5, 2, 6, 3, 1, 4}
25 |
26 | // Sorting the slice in ascending order
27 | sort.Ints(numbers)
28 |
29 | // Printing the sorted slice
30 | fmt.Println("Sorted integers:", numbers)
31 | }
32 | ```
33 |
34 | ### 🏃 How to Run
35 |
36 | 1. Ensure you have Go installed. If not, download it from [here](https://golang.org/dl/).
37 | 2. Clone this repository:
38 |
39 | ```bash
40 | git clone https://github.com/Rapter1990/go_sample_examples.git
41 | ```
42 |
43 | 3. Navigate to the `001_basic_sorting_with_integers` directory:
44 |
45 | ```bash
46 | cd go_sample_examples/026_sorting/001_basic_sorting_with_integers
47 | ```
48 |
49 | 4. Run the Go program:
50 |
51 | ```bash
52 | go run main.go
53 | ```
54 |
55 | ### 📦 Output
56 |
57 | When you run the program, the output will display the sorted integers:
58 |
59 | ```bash
60 | Sorted integers: [1 2 3 4 5 6]
61 | ```
--------------------------------------------------------------------------------
/026_sorting/002_sorting_strings/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Sorting Strings
2 |
3 | This repository demonstrates how to sort a slice of strings in Go using the built-in `sort` package. It provides an example of working with string sorting functionality in Go.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers sorting a slice of strings in ascending alphabetical order using the `sort.Strings` function.
9 | - Sorting strings is a common task in many applications, and Go provides a simple way to do this using the `sort` package.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```golang
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "sort"
20 | )
21 |
22 | func main() {
23 | // Slice of strings to sort
24 | strings := []string{"banana", "apple", "cherry"}
25 |
26 | // Sorting the slice in ascending order
27 | sort.Strings(strings)
28 |
29 | // Printing the sorted slice
30 | fmt.Println("Sorted strings:", strings)
31 | }
32 | ```
33 |
34 | ### 🏃 How to Run
35 |
36 | 1. Ensure you have Go installed. If not, download it from [here](https://golang.org/dl/).
37 | 2. Clone this repository:
38 |
39 | ```bash
40 | git clone https://github.com/Rapter1990/go_sample_examples.git
41 | ```
42 |
43 | 3. Navigate to the `002_sorting_strings` directory:
44 |
45 | ```bash
46 | cd go_sample_examples/026_sorting/002_sorting_strings
47 | ```
48 |
49 | 4. Run the Go program:
50 |
51 | ```bash
52 | go run main.go
53 | ```
54 |
55 | ### 📦 Output
56 |
57 | When you run the program, the output will display the sorted strings:
58 |
59 | ```bash
60 | Sorted strings: [apple banana cherry]
61 | ```
--------------------------------------------------------------------------------
/027_panic_and_defer/001_basic_example_of_defer/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Panic and Defer
2 |
3 | This repository demonstrates the basic usage of `defer` in Go, showcasing how to delay the execution of a function until the surrounding function returns. This is a common feature in Go used for resource cleanup, logging, and more.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers a simple use case of the `defer` statement in Go.
9 | - It includes an example where a function call is deferred, showing how it runs after the surrounding function finishes.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | )
20 |
21 | func main() {
22 |
23 | // The defer statement is used to delay the execution of a function until the surrounding function returns
24 | defer fmt.Println("This is deferred")
25 |
26 | fmt.Println("This happens first")
27 | }
28 | ```
29 |
30 | ### 🏃 How to Run
31 |
32 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
33 | 2. Clone this repository:
34 |
35 | ```bash
36 | git clone https://github.com/Rapter1990/go_sample_examples.git
37 | ```
38 |
39 | 3. Navigate to the `027_panic_and_defer/001_basic_example_of_defer` directory:
40 |
41 | ```bash
42 | cd go_sample_examples/027_panic_and_defer/001_basic_example_of_defer
43 | ```
44 |
45 | 4. Run the Go program:
46 |
47 | ```bash
48 | go run main.go
49 | ```
50 |
51 | ### 📦 Output
52 |
53 | When you run the program, you should see the following output:
54 |
55 | ```bash
56 | This happens first
57 | This is deferred
58 | ```
--------------------------------------------------------------------------------
/026_sorting/006_reverse_sorting/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Reverse Sorting
2 |
3 | This repository demonstrates how to sort a slice of integers in reverse order using Go's `sort` package. It showcases how to apply the `sort.Reverse` function to an integer slice to sort it in descending order.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers sorting a slice of integers in reverse order in Go.
9 | - It utilizes the `sort.Reverse` function along with `sort.IntSlice` to achieve reverse sorting of integers.
10 | - This is useful for sorting any numerical data in descending order.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```golang
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sort"
21 | )
22 |
23 | func main() {
24 |
25 | // Demonstrates how to sort in reverse order
26 |
27 | numbers := []int{5, 2, 6, 3, 1, 4}
28 | sort.Sort(sort.Reverse(sort.IntSlice(numbers)))
29 | fmt.Println("Reverse sorted integers:", numbers)
30 | }
31 | ```
32 |
33 | ### 🏃 How to Run
34 |
35 | 1. Ensure you have Go installed. If not, download it from [here](https://golang.org/dl/).
36 | 2. Clone this repository:
37 |
38 | ```bash
39 | git clone https://github.com/Rapter1990/go_sample_examples.git
40 | ```
41 |
42 | 3. Navigate to the `006_reverse_sorting` directory:
43 |
44 | ```bash
45 | cd go_sample_examples/026_sorting/006_reverse_sorting
46 | ```
47 |
48 | 4. Run the Go program:
49 |
50 | ```bash
51 | go run main.go
52 | ```
53 |
54 | ### 📦 Output
55 |
56 | When you run the program, the output will display the integers sorted in reverse order:
57 |
58 | ```bash
59 | Reverse sorted integers: [6 5 4 3 2 1]
60 | ```
--------------------------------------------------------------------------------
/030_json/007_custom_json_marshaling_and_unmarshaling/007_custom_json_marshaling_and_unmarshaling.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "strconv"
7 | )
8 |
9 | type Person7 struct {
10 | Name string
11 | Age int
12 | }
13 |
14 | // Custom Marshaling for Person
15 | func (p Person7) MarshalJSON() ([]byte, error) {
16 | return json.Marshal(struct {
17 | Name string `json:"name"`
18 | Age string `json:"age"`
19 | }{
20 | Name: p.Name,
21 | Age: strconv.Itoa(p.Age) + " years old",
22 | })
23 | }
24 |
25 | // Custom Unmarshaling for Person
26 | func (p *Person7) UnmarshalJSON(data []byte) error {
27 | var aux struct {
28 | Name string `json:"name"`
29 | Age string `json:"age"`
30 | }
31 | if err := json.Unmarshal(data, &aux); err != nil {
32 | return err
33 | }
34 |
35 | p.Name = aux.Name
36 | age, err := strconv.Atoi(aux.Age)
37 | if err != nil {
38 | return err
39 | }
40 | p.Age = age
41 | return nil
42 | }
43 |
44 | func main() {
45 |
46 | // This example shows how to implement custom marshaling and unmarshaling methods by overriding MarshalJSON and UnmarshalJSON for the Person struct
47 |
48 | person := Person7{
49 | Name: "John",
50 | Age: 30,
51 | }
52 |
53 | jsonData, err := json.Marshal(person)
54 | if err != nil {
55 | fmt.Println("Error encoding JSON:", err)
56 | return
57 | }
58 |
59 | fmt.Println("Custom Marshaled JSON:", string(jsonData))
60 |
61 | jsonString := `{"name":"Alice","age":"28"}`
62 | var newPerson Person7
63 |
64 | err = json.Unmarshal([]byte(jsonString), &newPerson)
65 | if err != nil {
66 | fmt.Println("Error decoding JSON:", err)
67 | return
68 | }
69 |
70 | fmt.Printf("Custom Unmarshaled Struct: %+v\n", newPerson)
71 | }
72 |
--------------------------------------------------------------------------------
/022_worker_pools/005_rate_limited_worker_pool/005_rate_limited_worker_pool.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | "time"
7 | )
8 |
9 | func rateLimitedWorker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
10 | defer wg.Done()
11 | for j := range jobs {
12 | fmt.Printf("Worker %d processing job %d\n", id, j)
13 | time.Sleep(500 * time.Millisecond) // Simulate work and rate limiting
14 | results <- j * 2
15 | }
16 | }
17 |
18 | func main() {
19 |
20 | // Rate-Limited Worker Pool
21 | // This example limits the rate at which jobs are processed by the workers
22 |
23 | /*
24 |
25 | How Rate Limiting Works Here:
26 | Rate Limiting Simulation:
27 | - The time.Sleep(500 * time.Millisecond) introduces a delay of 500 milliseconds before processing the next job.
28 | - This delay is meant to simulate the effect of rate limiting, where each worker can only process one job every 500 milliseconds.
29 |
30 | Job Processing:
31 | - Since there are multiple workers (3 in this case), and each job takes 500 milliseconds to process, the overall rate at which jobs are completed will be influenced by the number of workers and the processing time.
32 |
33 | */
34 |
35 | const numJobs = 5
36 | jobs := make(chan int, numJobs)
37 | results := make(chan int, numJobs)
38 |
39 | var wg sync.WaitGroup
40 |
41 | // Start workers
42 | for w := 1; w <= 3; w++ {
43 | wg.Add(1)
44 | go rateLimitedWorker(w, jobs, results, &wg)
45 | }
46 |
47 | // Send jobs to workers
48 | for j := 1; j <= numJobs; j++ {
49 | jobs <- j
50 | }
51 | close(jobs)
52 |
53 | // Wait for all workers to finish
54 | wg.Wait()
55 | close(results)
56 |
57 | // Collect results
58 | for result := range results {
59 | fmt.Println("Result:", result)
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/020_timers/001_simple_timer/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Simple Timer
2 |
3 | This example demonstrates the usage of a simple timer in Go. The program shows how to create a timer that fires after a specified duration and performs an action after the timer expires.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the basic usage of Go's
time.Timer to schedule an event after a delay.
9 | - The program waits for the timer to fire after 2 seconds, and once the timer fires, it prints a message to the console.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "time"
20 | )
21 |
22 | func main() {
23 |
24 | // Basic Example: Simple Timer
25 | // Create a basic timer that fires after 2 seconds
26 |
27 | // Create a timer that will fire after 2 seconds
28 | timer := time.NewTimer(2 * time.Second)
29 |
30 | fmt.Println("Waiting for the timer to fire...")
31 |
32 | // Block until the timer's channel sends a value
33 | <-timer.C
34 |
35 | fmt.Println("Timer fired!")
36 | }
37 | ```
38 |
39 | ### 🏃 How to Run
40 |
41 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
42 | 2. Clone this repository:
43 |
44 | ```bash
45 | git clone https://github.com/Rapter1990/go_sample_examples.git
46 | ```
47 |
48 | 3. Navigate to the `001_simple_timer` directory:
49 |
50 | ```bash
51 | cd go_sample_examples/020_timers/001_simple_timer
52 | ```
53 |
54 | 4. Run the Go program:
55 |
56 | ```bash
57 | go run 001_simple_timer.go
58 | ```
59 |
60 | ### 📦 Output
61 |
62 | When you run the program, you should see the following output:
63 |
64 | ```bash
65 | Waiting for the timer to fire...
66 | Timer fired!
67 | ```
--------------------------------------------------------------------------------
/027_panic_and_defer/002_multiple_defer/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Panic and Defer (Multiple `defer` Statements)
2 |
3 | This repository demonstrates the usage of multiple `defer` statements in Go, showcasing how they are executed in a Last In, First Out (LIFO) order. The `defer` keyword is commonly used to schedule tasks such as resource cleanup that should occur after the surrounding function completes.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the usage of multiple `defer` statements in Go.
9 | - It shows how the `defer` statements are executed in reverse order (LIFO) after the main function completes.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | )
20 |
21 | func main() {
22 |
23 | // multiple defer statements are used, they are executed in Last In, First Out (LIFO) order
24 | defer fmt.Println("First defer")
25 | defer fmt.Println("Second defer")
26 | defer fmt.Println("Third defer")
27 |
28 | fmt.Println("Executing main function")
29 | }
30 | ```
31 |
32 | ### 🏃 How to Run
33 |
34 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
35 | 2. Clone this repository:
36 |
37 | ```bash
38 | git clone https://github.com/Rapter1990/go_sample_examples.git
39 | ```
40 |
41 | 3. Navigate to the `027_panic_and_defer/002_multiple_defer` directory:
42 |
43 | ```bash
44 | cd go_sample_examples/027_panic_and_defer/002_multiple_defer
45 | ```
46 |
47 | 4. Run the Go program:
48 |
49 | ```bash
50 | go run main.go
51 | ```
52 |
53 | ### 📦 Output
54 |
55 | When you run the program, you should see the following output:
56 |
57 | ```bash
58 | Executing main function
59 | Third defer
60 | Second defer
61 | First defer
62 | ```
--------------------------------------------------------------------------------
/018_closing_channel/03_closing_channels_in_multiple_goroutines/03_closing_channels_in_multiple_goroutines.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | )
7 |
8 | // Each worker sends the integers 0, 1, 2 to the channel ch
9 | func worker(ch chan int, wg *sync.WaitGroup) {
10 | defer wg.Done() // wg.Done() is called to indicate that the worker has finished its task
11 | for i := 0; i < 3; i++ {
12 | ch <- i
13 | }
14 | }
15 |
16 | func main() {
17 |
18 | // Closing Channels in Multiple Goroutines
19 |
20 | // Three worker goroutines send values to the channel.
21 | // The channel is closed after all the workers finish their tasks.
22 | // The sync.WaitGroup is used to synchronize the workers and close the channel only after all of them have finished
23 |
24 | // ch: A channel of type int used for communication between goroutines.
25 | ch := make(chan int)
26 |
27 | // wg: A sync.WaitGroup to synchronize the completion of multiple goroutines.
28 | var wg sync.WaitGroup
29 |
30 | // Start 3 worker goroutines
31 | // // Three worker goroutines are started. Each worker will send values (0, 1, 2) to the channel ch
32 | for i := 0; i < 3; i++ {
33 | wg.Add(1) // wg.Add(1) increments the wait group counter by 1 for each worker goroutine
34 | go worker(ch, &wg)
35 | }
36 |
37 | go func() {
38 | wg.Wait() // A separate goroutine waits for all worker goroutines to complete using wg.Wait()
39 | close(ch) // Close the channel when all workers are done
40 | }()
41 |
42 | // Receiving values until the channel is closed
43 | for value := range ch {
44 | fmt.Println("Received:", value)
45 | }
46 |
47 | fmt.Println("All workers done, channel closed.")
48 |
49 | /*
50 | Goroutine Execution Order
51 | Each worker goroutine sends three integers (0, 1, 2) to the channel ch.
52 | Since the goroutines execute concurrently, the exact order of sending is not guaranteed
53 | */
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/020_timers/004_using_time_after/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Using `time.After`
2 |
3 | This repository demonstrates how to use the `time.After` function in Go. It includes an example of creating a simple timer that waits for a specified duration and fires once, providing a straightforward alternative to `time.NewTimer`.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers how to use the
time.After function in Go to wait for a specific duration.
9 | - The
time.After function returns a channel that will receive the current time after the specified duration has passed.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "time"
20 | )
21 |
22 | func main() {
23 |
24 | // Using time.After
25 | // time.After is a simpler alternative to time.NewTimer for creating a timer that only needs to fire once.
26 | // It returns a channel that will receive the current time after the specified duration.
27 |
28 | fmt.Println("Waiting for 2 seconds...")
29 |
30 | // Wait for 2 seconds using time.After
31 | <-time.After(2 * time.Second)
32 |
33 | fmt.Println("2 seconds passed.")
34 | }
35 | ```
36 |
37 | ### 🏃 How to Run
38 |
39 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
40 | 2. Clone this repository:
41 |
42 | ```bash
43 | git clone https://github.com/Rapter1990/go_sample_examples.git
44 | ```
45 |
46 | 3. Navigate to the `004_using_time_after` directory:
47 |
48 | ```bash
49 | cd go_sample_examples/020_timers/004_using_time_after
50 | ```
51 |
52 | 4. Run the Go program:
53 |
54 | ```bash
55 | go run 004_using_time_after.go
56 | ```
57 |
58 | ### 📦 Output
59 |
60 | When you run the program, you should see the following output:
61 |
62 | ```bash
63 | Waiting for 2 seconds...
64 | 2 seconds passed.
65 | ```
--------------------------------------------------------------------------------
/030_json/001_basic_encoding_json/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Basic JSON Encoding
2 |
3 | This repository demonstrates how to encode Go structs into JSON format using Go's standard library package `encoding/json`. It showcases the basic steps required to marshal Go data structures into JSON format for serialization.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers basic JSON encoding using Go structs and the `json.Marshal` function.
9 | - It demonstrates how to convert a Go struct into JSON format, handling potential errors during the encoding process.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "encoding/json"
19 | "fmt"
20 | )
21 |
22 | type Person struct {
23 | Name string
24 | Age int
25 | Country string
26 | }
27 |
28 | func main() {
29 |
30 | // This example shows how to convert a Go struct into JSON format using json.Marshal
31 |
32 | person := Person{
33 | Name: "John",
34 | Age: 30,
35 | Country: "USA",
36 | }
37 |
38 | jsonData, err := json.Marshal(person)
39 | if err != nil {
40 | fmt.Println("Error encoding JSON:", err)
41 | return
42 | }
43 |
44 | fmt.Println(string(jsonData))
45 | }
46 | ```
47 |
48 | ### 🏃 How to Run
49 |
50 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
51 | 2. Clone this repository:
52 |
53 | ```bash
54 | git clone https://github.com/Rapter1990/go_sample_examples.git
55 | ```
56 |
57 | 3. Navigate to the `001_basic_encoding_json` directory:
58 |
59 | ```bash
60 | cd go_sample_examples/030_json/001_basic_encoding_json
61 | ```
62 |
63 | 4. Run the Go program:
64 |
65 | ```bash
66 | go run 001_basic_encoding_json.go
67 | ```
68 |
69 | ### 📦 Output
70 |
71 | When you run the program, you should see the following output:
72 |
73 | ```json
74 | {"Name":"John","Age":30,"Country":"USA"}
75 | ```
--------------------------------------------------------------------------------
/002_variables/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | // Constants
9 | const Pi = 3.14159
10 |
11 | // Enumerations using iota
12 | const (
13 | Red = iota // The iota keyword represents successive integer constants 0, 1, 2,…
14 | Green
15 | Blue
16 | )
17 |
18 | func main() {
19 |
20 | fmt.Println("-----------------------------------------------------------------------------------")
21 |
22 | // Integer variables
23 | var intVar int = 10
24 | var intAuto = 20 // Type inference
25 |
26 | // Long integer (int64)
27 | var longVar int64 = 10000000000
28 |
29 | // Floating-point variables
30 | var floatVar float32 = 3.14
31 | var doubleVar float64 = math.Pi // Double precision floating-point
32 |
33 | // String variables
34 | var strVar string = "Hello, Go!"
35 | var strAuto = "Welcome to Go programming!" // Type inference
36 |
37 | // Boolean variable
38 | var boolVar bool = true
39 |
40 | // Using short variable declaration
41 | name := "John Doe"
42 | age := 30
43 | salary := 55000.50
44 | isEmployed := true
45 |
46 | // Printing variables
47 | fmt.Println("Integer variable:", intVar)
48 | fmt.Println("Auto-inferred integer:", intAuto)
49 | fmt.Println("Long variable (int64):", longVar)
50 | fmt.Println("Float variable:", floatVar)
51 | fmt.Println("Double variable:", doubleVar)
52 | fmt.Println("String variable:", strVar)
53 | fmt.Println("Auto-inferred string:", strAuto)
54 | fmt.Println("Boolean variable:", boolVar)
55 |
56 | // Printing short-declared variables
57 | fmt.Println("Name:", name)
58 | fmt.Println("Age:", age)
59 | fmt.Println("Salary:", salary)
60 | fmt.Println("Is Employed:", isEmployed)
61 |
62 | // Constants
63 | fmt.Println("Constant Pi:", Pi)
64 |
65 | // Enumerations
66 | fmt.Println("Red:", Red)
67 | fmt.Println("Green:", Green)
68 | fmt.Println("Blue:", Blue)
69 |
70 | fmt.Println("-----------------------------------------------------------------------------------")
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/026_sorting/008_sorting_a_map_by_keys/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Sorting a Map by Keys
2 |
3 | This repository demonstrates how to sort a map by its keys in Go. It showcases how to extract keys from a map, sort them using the `sort.Strings` function, and then iterate over the sorted keys to access the corresponding values.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers sorting a Go map by its keys.
9 | - The map contains key-value pairs of names and ages, which are sorted alphabetically by the key (name).
10 | - By extracting the map's keys, sorting them, and iterating over the sorted list, the values can be printed in order of the keys.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```golang
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sort"
21 | )
22 |
23 | func main() {
24 |
25 | // Show how to sort a map by its keys
26 |
27 | ages := map[string]int{
28 | "Alice": 25,
29 | "Charlie": 20,
30 | "Bob": 30,
31 | }
32 |
33 | keys := make([]string, 0, len(ages))
34 | for k := range ages {
35 | keys = append(keys, k)
36 | }
37 |
38 | sort.Strings(keys)
39 |
40 | fmt.Println("Sorted by keys:")
41 | for _, k := range keys {
42 | fmt.Println(k, ages[k])
43 | }
44 | }
45 | ```
46 |
47 | ### 🏃 How to Run
48 |
49 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
50 | 2. Clone this repository:
51 |
52 | ```bash
53 | git clone https://github.com/Rapter1990/go_sample_examples.git
54 | ```
55 |
56 | 3. Navigate to the `008_sorting_a_map_by_keys` directory:
57 |
58 | ```bash
59 | cd go_sample_examples/026_sorting/008_sorting_a_map_by_keys
60 | ```
61 |
62 | 4. Run the Go program:
63 |
64 | ```bash
65 | go run main.go
66 | ```
67 |
68 | ### 📦 Output
69 |
70 | When you run the program, the output will display the map entries sorted by their keys:
71 |
72 | ```bash
73 | Sorted by keys:
74 | Alice 25
75 | Bob 30
76 | Charlie 20
77 | ```
--------------------------------------------------------------------------------
/030_json/005_custom_json_field_names/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Custom JSON Field Names
2 |
3 | This repository demonstrates how to customize JSON field names in Go using struct tags. It showcases how to use Go's `encoding/json` package to serialize and deserialize struct fields with custom names.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers how to use struct tags to customize JSON field names during encoding and decoding.
9 | - It demonstrates defining a struct with custom JSON field names using the `json` struct tag.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "encoding/json"
19 | "fmt"
20 | )
21 |
22 | type Person5 struct {
23 | Name string `json:"full_name"`
24 | Age int `json:"age"`
25 | Country string `json:"country"`
26 | }
27 |
28 | func main() {
29 |
30 | // This example demonstrates how to customize JSON field names using struct tags (json:"field_name")
31 |
32 | person := Person5{
33 | Name: "John Doe",
34 | Age: 30,
35 | Country: "USA",
36 | }
37 |
38 | jsonData, err := json.Marshal(person)
39 | if err != nil {
40 | fmt.Println("Error encoding JSON:", err)
41 | return
42 | }
43 |
44 | fmt.Println(string(jsonData))
45 | }
46 | ```
47 |
48 | ### 🏃 How to Run
49 |
50 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
51 | 2. Clone this repository:
52 |
53 | ```bash
54 | git clone https://github.com/Rapter1990/go_sample_examples.git
55 | ```
56 |
57 | 3. Navigate to the `005_custom_json_field_names` directory:
58 |
59 | ```bash
60 | cd go_sample_examples/030_json/005_custom_json_field_names
61 | ```
62 |
63 | 4. Run the Go program:
64 |
65 | ```bash
66 | go run 005_custom_json_field_names.go
67 | ```
68 |
69 | ### 📦 Output
70 |
71 | When you run the program, you should see the following output:
72 |
73 | ```json
74 | {"full_name":"John Doe","age":30,"country":"USA"}
75 | ```
--------------------------------------------------------------------------------
/027_panic_and_defer/009_closing_resources_with_defer/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Closing Resources with Defer
2 |
3 | This repository demonstrates how to use `defer` in Go to ensure that resources, such as files, are properly closed after use. It highlights the importance of deferring cleanup actions, such as closing files, to avoid resource leaks, even when an error occurs.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the usage of `defer` to manage resource cleanup in Go.
9 | - The `defer` statement ensures that the file is closed properly after it is no longer needed, even if the program encounters an error.
10 | - This example demonstrates a basic use case of opening and closing a file, with error handling for file operations.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "os"
21 | )
22 |
23 | func main() {
24 |
25 | // This example demonstrates using defer to ensure resources like files are closed properly, even if an error occurs
26 |
27 | file, err := os.Open("example.txt")
28 | if err != nil {
29 | panic(err)
30 | }
31 | defer file.Close()
32 |
33 | fmt.Println("File opened successfully")
34 | // Processing file content...
35 | }
36 | ```
37 |
38 | ### 🏃 How to Run
39 |
40 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
41 | 2. Clone this repository:
42 |
43 | ```bash
44 | git clone https://github.com/Rapter1990/go_sample_examples.git
45 | ```
46 |
47 | 3. Navigate to the `027_panic_and_defer/009_closing_resources_with_defer` directory:
48 |
49 | ```bash
50 | cd go_sample_examples/027_panic_and_defer/009_closing_resources_with_defer
51 | ```
52 |
53 | 4. Run the Go program:
54 |
55 | ```bash
56 | go run 009_closing_resources_with_defer.go
57 | ```
58 |
59 | ### 📦 Output
60 |
61 | When you run the program, you should see the following output:
62 |
63 | ```bash
64 | File opened successfully
65 | ```
--------------------------------------------------------------------------------
/030_json/006_omitting_empty_fields/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Omitting Empty Fields in JSON
2 |
3 | This repository demonstrates how to omit empty fields from JSON output in Go using the `omitempty` struct tag. It showcases how to use Go's `encoding/json` package to exclude fields that have zero values during serialization.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers how to use the `omitempty` tag to exclude empty or zero-value fields from JSON output.
9 | - It demonstrates defining a struct where certain fields are omitted from the JSON output if they have default values (such as an empty string or zero).
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "encoding/json"
19 | "fmt"
20 | )
21 |
22 | type Person6 struct {
23 | Name string `json:"name"`
24 | Age int `json:"age,omitempty"`
25 | Country string `json:"country,omitempty"`
26 | }
27 |
28 | func main() {
29 |
30 | // This example shows how to omit empty fields from the JSON output using the omitempty struct tag
31 |
32 | person := Person6{
33 | Name: "John Doe",
34 | }
35 |
36 | jsonData, err := json.Marshal(person)
37 | if err != nil {
38 | fmt.Println("Error encoding JSON:", err)
39 | return
40 | }
41 |
42 | fmt.Println(string(jsonData))
43 | }
44 | ```
45 |
46 | ### 🏃 How to Run
47 |
48 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
49 | 2. Clone this repository:
50 |
51 | ```bash
52 | git clone https://github.com/Rapter1990/go_sample_examples.git
53 | ```
54 |
55 | 3. Navigate to the `006_omitting_empty_fields` directory:
56 |
57 | ```bash
58 | cd go_sample_examples/030_json/006_omitting_empty_fields
59 | ```
60 |
61 | 4. Run the Go program:
62 |
63 | ```bash
64 | go run 006_omitting_empty_fields.go
65 | ```
66 |
67 | ### 📦 Output
68 |
69 | When you run the program, you should see the following output:
70 |
71 | ```json
72 | {"name":"John Doe"}
73 | ```
--------------------------------------------------------------------------------
/027_panic_and_defer/010_defer_with_https_requests/README.md:
--------------------------------------------------------------------------------
1 | Here’s the `README.md` for the `defer with HTTP requests` example following the same format:
2 |
3 | ---
4 |
5 | # Go Sample Example - Defer with HTTP Requests
6 |
7 | This repository demonstrates how to use `defer` in Go to manage resources when making HTTP requests. It shows how `defer` can be used to ensure that resources like HTTP response bodies are closed properly after use.
8 |
9 | ## 📖 Information
10 |
11 |
12 | - This example covers the usage of `defer` to handle resource cleanup in HTTP requests.
13 | - It highlights how to use `defer` to close the HTTP response body, ensuring that resources are released even if an error occurs during the request or response processing.
14 | - This example involves making an HTTP GET request and reading the response body.
15 |
16 |
17 | ## 💻 Code Example
18 |
19 | ```go
20 | package main
21 |
22 | import (
23 | "fmt"
24 | "io"
25 | "net/http"
26 | )
27 |
28 | func main() {
29 |
30 | // using defer to close the response body of an HTTP request
31 |
32 | resp, err := http.Get("https://www.google.com")
33 | if err != nil {
34 | panic(err)
35 | }
36 | defer resp.Body.Close()
37 |
38 | body, err := io.ReadAll(resp.Body)
39 | if err != nil {
40 | panic(err)
41 | }
42 | fmt.Println(string(body))
43 | }
44 | ```
45 |
46 | ### 🏃 How to Run
47 |
48 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
49 | 2. Clone this repository:
50 |
51 | ```bash
52 | git clone https://github.com/Rapter1990/go_sample_examples.git
53 | ```
54 |
55 | 3. Navigate to the `027_panic_and_defer/010_defer_with_https_requests` directory:
56 |
57 | ```bash
58 | cd go_sample_examples/027_panic_and_defer/010_defer_with_https_requests
59 | ```
60 |
61 | 4. Run the Go program:
62 |
63 | ```bash
64 | go run 010_defer_with_https_requests.go
65 | ```
66 |
67 | ### 📦 Output
68 | ```bash
69 | html response from https://www.google.com
70 | ```
71 |
--------------------------------------------------------------------------------
/027_panic_and_defer/005_panic_with_recover/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Panic with Recover
2 |
3 | This repository demonstrates the use of `panic` along with `recover` in Go. It showcases how a panicking program can regain control using the `recover` function within a deferred function, preventing the program from crashing.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the usage of `panic` and `recover` in Go.
9 | - The `panic` function triggers a panic, which begins unwinding the stack, while the `recover` function is used to catch the panic and allow the program to continue executing.
10 | - This technique can be used to handle unexpected errors and avoid abrupt termination of the program.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | )
21 |
22 | func main() {
23 |
24 | // The recover function is used to regain control of a panicking goroutine.
25 | // It can be used within a deferred function to catch a panic and prevent the program from crashing
26 |
27 | defer func() {
28 | if r := recover(); r != nil {
29 | fmt.Println("Recovered from panic:", r)
30 | }
31 | }()
32 | fmt.Println("Starting main")
33 | panic("A severe error occurred")
34 | fmt.Println("This will not be printed")
35 | }
36 | ```
37 |
38 | ### 🏃 How to Run
39 |
40 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
41 | 2. Clone this repository:
42 |
43 | ```bash
44 | git clone https://github.com/Rapter1990/go_sample_examples.git
45 | ```
46 |
47 | 3. Navigate to the `027_panic_and_defer/005_panic_with_recover` directory:
48 |
49 | ```bash
50 | cd go_sample_examples/027_panic_and_defer/005_panic_with_recover
51 | ```
52 |
53 | 4. Run the Go program:
54 |
55 | ```bash
56 | go run main.go
57 | ```
58 |
59 | ### 📦 Output
60 |
61 | When you run the program, you should see the following output:
62 |
63 | ```bash
64 | Starting main
65 | Recovered from panic: A severe error occurred
66 | ```
--------------------------------------------------------------------------------
/027_panic_and_defer/004_basic_example_of_panic/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Panic (Basic Example of Panic)
2 |
3 | This repository demonstrates a basic use of the `panic` function in Go. It showcases how a `panic` can abruptly stop the flow of the program and unwind the stack, terminating the program execution with an error.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the basic usage of the `panic` function in Go.
9 | - The `panic` function is used to handle unexpected situations or serious errors that make further program execution impossible.
10 | - Once a panic is triggered, the program begins unwinding the stack and prints an error message, terminating the process.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | )
21 |
22 | func main() {
23 |
24 | // The panic function is used to stop the ordinary flow of control and start panicking,
25 | // which in turn begins unwinding the stack
26 |
27 | fmt.Println("Start of main")
28 | panic("Something went wrong")
29 | fmt.Println("This will not be printed")
30 | }
31 | ```
32 |
33 | ### 🏃 How to Run
34 |
35 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
36 | 2. Clone this repository:
37 |
38 | ```bash
39 | git clone https://github.com/Rapter1990/go_sample_examples.git
40 | ```
41 |
42 | 3. Navigate to the `027_panic_and_defer/004_basic_example_of_panic` directory:
43 |
44 | ```bash
45 | cd go_sample_examples/027_panic_and_defer/004_basic_example_of_panic
46 | ```
47 |
48 | 4. Run the Go program:
49 |
50 | ```bash
51 | go run main.go
52 | ```
53 |
54 | ### 📦 Output
55 |
56 | When you run the program, you should see the following output:
57 |
58 | ```bash
59 | Start of main
60 | panic: Something went wrong
61 |
62 | goroutine 1 [running]:
63 | main.main()
64 | /path/to/your-repository/go_sample_examples/027_panic_and_defer/004_basic_example_of_panic/004_basic_example_of_panic.go:13 +0x59
65 | exit status 2
66 | ```
--------------------------------------------------------------------------------
/025_atomic_counters/005_atomic_pointer/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Atomic Pointer
2 |
3 | This repository demonstrates how to atomically load and store a pointer value in Go using the `sync/atomic` package. It showcases safe concurrent updates to pointer values, ensuring data integrity across goroutines.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the use of atomic operations to load and store a pointer value in a thread-safe manner.
9 | - It demonstrates the use of `atomic.Value` for storing and retrieving pointer values concurrently between goroutines.
10 | - The example includes updating the value in a separate goroutine and safely retrieving it using atomic operations.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sync/atomic"
21 | )
22 |
23 | func main() {
24 |
25 | // Atomic Pointer
26 | // demonstrate how to atomically load and store a pointer value
27 |
28 | var data atomic.Value
29 |
30 | // Store an initial value
31 | data.Store("Initial Value")
32 |
33 | // Load and print the current value
34 | fmt.Println("Current Value:", data.Load())
35 |
36 | // Start a goroutine to change the value
37 | go func() {
38 | data.Store("New Value")
39 | }()
40 |
41 | // Load and print the new value
42 | fmt.Println("New Value:", data.Load())
43 | }
44 | ```
45 |
46 | ### 🏃 How to Run
47 |
48 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
49 | 2. Clone this repository:
50 |
51 | ```bash
52 | git clone https://github.com/Rapter1990/go_sample_examples.git
53 | ```
54 |
55 | 3. Navigate to the **025_atomic_counters/005_atomic_pointer** directory:
56 |
57 | ```bash
58 | cd go_sample_examples/025_atomic_counters/005_atomic_pointer
59 | ```
60 |
61 | 4. Run the Go program:
62 |
63 | ```bash
64 | go run main.go
65 | ```
66 |
67 | ### 📦 Output
68 |
69 | When you run the program, you should see an output similar to:
70 |
71 | ```bash
72 | Current Value: Initial Value
73 | New Value: New Value
74 | ```
--------------------------------------------------------------------------------
/020_timers/003_reset_timer/README.md:
--------------------------------------------------------------------------------
1 | Here is the `README.md` for the Go example of resetting a timer:
2 |
3 | # Go Sample Example - Resetting a Timer
4 |
5 | This repository demonstrates how to reset a timer in Go. It includes an example of using the `Reset` method to modify the duration of an existing timer, allowing it to restart with a new duration even after it has been started.
6 |
7 | ## 📖 Information
8 |
9 |
10 | - This example shows how to use the
Reset method to reset a timer to a new duration in Go.
11 | - If the timer had already fired, it will restart with the new duration and fire after the updated time.
12 |
13 |
14 | ## 💻 Code Example
15 |
16 | ```go
17 | package main
18 |
19 | import (
20 | "fmt"
21 | "time"
22 | )
23 |
24 | func main() {
25 |
26 | // Resetting a Timer
27 | // The Reset method is used to reset a timer to a new duration.
28 | // If the timer had already fired, it will restart with the new duration
29 |
30 | // Create a timer that will fire after 2 seconds
31 | timer := time.NewTimer(2 * time.Second)
32 |
33 | // Start a goroutine to reset the timer after 1 second
34 | go func() {
35 | time.Sleep(1 * time.Second)
36 | timer.Reset(4 * time.Second)
37 | fmt.Println("Timer reset to 4 seconds.")
38 | }()
39 |
40 | // Wait for the timer to fire
41 | <-timer.C
42 | fmt.Println("Timer fired!")
43 | }
44 | ```
45 |
46 | ### 🏃 How to Run
47 |
48 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
49 | 2. Clone this repository:
50 |
51 | ```bash
52 | git clone https://github.com/Rapter1990/go_sample_examples.git
53 | ```
54 |
55 | 3. Navigate to the `003_reset_timer` directory:
56 |
57 | ```bash
58 | cd go_sample_examples/020_timers/003_reset_timer
59 | ```
60 |
61 | 4. Run the Go program:
62 |
63 | ```bash
64 | go run 003_reset_timer.go
65 | ```
66 |
67 | ### 📦 Output
68 |
69 | When you run the program, you should see the following output:
70 |
71 | ```bash
72 | Timer reset to 4 seconds.
73 | Timer fired!
74 | ```
--------------------------------------------------------------------------------
/005_function/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | // Function to swap two strings
8 | func swap(a, b string) (string, string) {
9 | return b, a
10 | }
11 |
12 | // Function to calculate the sum of integers
13 | func sum(a, b int) int {
14 | return a + b
15 | }
16 |
17 | // Variadic function to calculate the sum of multiple integers
18 | func variadicSum(numbers ...int) int {
19 | total := 0
20 | for _, num := range numbers {
21 | total += num
22 | }
23 | return total
24 | }
25 |
26 | // Function to create a closure
27 | func makeMultiplier(factor int) func(int) int {
28 | return func(x int) int {
29 | return x * factor
30 | }
31 | }
32 |
33 | // Recursive function to calculate factorial
34 | func factorial(n int) int {
35 | if n == 0 {
36 | return 1
37 | }
38 | return n * factorial(n-1)
39 | }
40 |
41 | func main() {
42 |
43 | fmt.Println("-----------------------------------------------------------------------------------")
44 |
45 | // Using the swap function
46 | a, b := "hello", "world"
47 | swappedA, swappedB := swap(a, b)
48 | fmt.Printf("Swapped values: %s, %s\n", swappedA, swappedB)
49 |
50 | fmt.Println("-----------------------------------------------------------------------------------")
51 |
52 | // Using the sum function
53 | fmt.Printf("Sum of 5 and 7: %d\n", sum(5, 7))
54 |
55 | fmt.Println("-----------------------------------------------------------------------------------")
56 |
57 | // Using the variadicSum function
58 | fmt.Printf("Sum of 1, 2, 3, 4, 5: %d\n", variadicSum(1, 2, 3, 4, 5))
59 |
60 | fmt.Println("-----------------------------------------------------------------------------------")
61 |
62 | // Using the closure
63 | multiplierBy2 := makeMultiplier(2)
64 | fmt.Printf("5 multiplied by 2: %d\n", multiplierBy2(5))
65 |
66 | fmt.Println("-----------------------------------------------------------------------------------")
67 |
68 | // Using the factorial function
69 | fmt.Printf("Factorial of 5: %d\n", factorial(5))
70 |
71 | fmt.Println("-----------------------------------------------------------------------------------")
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/027_panic_and_defer/003_defer_with_function_call/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Panic and Defer (Defer with File Operations)
2 |
3 | This repository demonstrates how to use `defer` statements in Go for resource cleanup, such as closing files. It shows how to handle file operations safely by ensuring that resources are released even if an error occurs during program execution.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers how `defer` is used in Go to close files and clean up resources automatically.
9 | - It includes file creation, writing to the file, and ensuring proper resource cleanup using `defer` to close the file.
10 | - It also demonstrates basic error handling with `panic` in case of file operation failures.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "os"
21 | )
22 |
23 | func main() {
24 |
25 | // use defer to call a function that cleans up resources, such as closing a file
26 | file, err := os.Create("example.txt")
27 | if err != nil {
28 | panic(err)
29 | }
30 | defer file.Close()
31 |
32 | _, err = file.WriteString("Hello, Go!")
33 | if err != nil {
34 | panic(err)
35 | }
36 | fmt.Println("File written successfully")
37 | }
38 | ```
39 |
40 | ### 🏃 How to Run
41 |
42 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
43 | 2. Clone this repository:
44 |
45 | ```bash
46 | git clone https://github.com/Rapter1990/go_sample_examples.git
47 | ```
48 |
49 | 3. Navigate to the `027_panic_and_defer/003_defer_with_function_call` directory:
50 |
51 | ```bash
52 | cd go_sample_examples/027_panic_and_defer/003_defer_with_function_call
53 | ```
54 |
55 | 4. Run the Go program:
56 |
57 | ```bash
58 | go run main.go
59 | ```
60 |
61 | ### 📦 Output
62 |
63 | When you run the program, you should see the following output:
64 |
65 | ```bash
66 | File written successfully
67 | ```
68 |
69 | Additionally, a new file `example.txt` will be created with the content:
70 |
71 | ```txt
72 | Hello, Go!
73 | ```
--------------------------------------------------------------------------------
/018_closing_channel/05_panic_when_closing_an_already_closed_channel/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Panic When Closing an Already Closed Channel
2 |
3 | This repository demonstrates what happens when you attempt to close a channel that has already been closed in Go. It showcases how to handle such a situation gracefully using the `recover()` function.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example shows the behavior of closing an already closed channel in Go, which results in a panic.
9 | - It demonstrates how to use `recover()` to handle the panic and continue execution without crashing the program.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import "fmt"
18 |
19 | func main() {
20 |
21 | // Panic when Closing an Already Closed Channel
22 |
23 | // Closing an already closed channel will cause a panic.
24 | // In this example, the recover() function is used to handle the panic gracefully
25 |
26 | ch := make(chan int)
27 | close(ch) // Close the channel
28 |
29 | defer func() {
30 | if r := recover(); r != nil {
31 | fmt.Println("Recovered from panic:", r)
32 | }
33 | }()
34 |
35 | // Attempting to close an already closed channel will cause a panic
36 | close(ch)
37 |
38 | fmt.Println("This line will not be executed")
39 | }
40 | ```
41 |
42 | ### 🏃 How to Run
43 |
44 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
45 | 2. Clone this repository:
46 |
47 | ```bash
48 | git clone https://github.com/Rapter1990/go_sample_examples.git
49 | ```
50 |
51 | 3. Navigate to the `018_closing_channel/05_panic_when_closing_an_already_closed_channel` directory:
52 |
53 | ```bash
54 | cd go_sample_examples/018_closing_channel/05_panic_when_closing_an_already_closed_channel
55 | ```
56 |
57 | 4. Run the Go program:
58 |
59 | ```bash
60 | go run 05_panic_when_closing_an_already_closed_channel.go
61 | ```
62 |
63 | ### 📦 Output
64 |
65 | When you run the program, you should see the following output:
66 |
67 | ```bash
68 | Recovered from panic: close of closed channel
69 | ```
70 |
--------------------------------------------------------------------------------
/026_sorting/003_sorting_by_custom_slice/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Sorting by Custom Slice
2 |
3 | This repository demonstrates how to sort a slice of structs in Go using the built-in `sort.Slice` function. It provides an example of custom sorting based on a specific field, like sorting by age.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers sorting a slice of structs in Go using custom criteria.
9 | - It showcases sorting a slice of `Person` structs by their `Age` field in ascending order using the `sort.Slice` function.
10 | - Sorting slices of structs with custom logic is a common task in Go, and this example illustrates how to implement it efficiently.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```golang
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sort"
21 | )
22 |
23 | // Define the Person struct with Name and Age fields
24 | type Person struct {
25 | Name string
26 | Age int
27 | }
28 |
29 | func main() {
30 | // Slice of Person structs to sort
31 | people := []Person{
32 | {"Alice", 25},
33 | {"Bob", 30},
34 | {"Charlie", 20},
35 | }
36 |
37 | // Sorting the slice of structs by Age field in ascending order
38 | sort.Slice(people, func(i, j int) bool {
39 | return people[i].Age < people[j].Age
40 | })
41 |
42 | // Printing the sorted slice
43 | fmt.Println("Sorted by age:", people)
44 | }
45 | ```
46 |
47 | ### 🏃 How to Run
48 |
49 | 1. Ensure you have Go installed. If not, download it from [here](https://golang.org/dl/).
50 | 2. Clone this repository:
51 |
52 | ```bash
53 | git clone https://github.com/Rapter1990/go_sample_examples.git
54 | ```
55 |
56 | 3. Navigate to the `003_sorting_by_custom_slice` directory:
57 |
58 | ```bash
59 | cd go_sample_examples/026_sorting/003_sorting_by_custom_slice
60 | ```
61 |
62 | 4. Run the Go program:
63 |
64 | ```bash
65 | go run main.go
66 | ```
67 |
68 | ### 📦 Output
69 |
70 | When you run the program, the output will display the sorted slice of `Person` structs by their age:
71 |
72 | ```bash
73 | Sorted by age: [{Charlie 20} {Alice 25} {Bob 30}]
74 | ```
--------------------------------------------------------------------------------
/027_panic_and_defer/006_panic_with_defer/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Panic with Defer
2 |
3 | This repository demonstrates the use of `panic` along with `defer` in Go. It showcases how deferred functions are executed even in the event of a panic, making them useful for cleanup tasks or ensuring certain operations are completed.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the usage of `panic` and `defer` in Go.
9 | - The `panic` function triggers a panic that halts normal execution, while the `defer` function ensures that certain code will still run after a panic, typically for cleanup or logging purposes.
10 | - This technique can help ensure that important operations, such as resource deallocation, are still performed when an error occurs.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | )
21 |
22 | func main() {
23 |
24 | // Deferred functions will still run even if a panic occurs. This is useful for cleanup tasks.
25 |
26 | defer fmt.Println("This will run even if panic occurs")
27 | panic("Panic in main function")
28 | fmt.Println("This will not be printed")
29 | }
30 | ```
31 |
32 | ### 🏃 How to Run
33 |
34 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
35 | 2. Clone this repository:
36 |
37 | ```bash
38 | git clone https://github.com/Rapter1990/go_sample_examples.git
39 | ```
40 |
41 | 3. Navigate to the `027_panic_and_defer/006_panic_with_defer` directory:
42 |
43 | ```bash
44 | cd go_sample_examples/027_panic_and_defer/006_panic_with_defer
45 | ```
46 |
47 | 4. Run the Go program:
48 |
49 | ```bash
50 | go run main.go
51 | ```
52 |
53 | ### 📦 Output
54 |
55 | When you run the program, you should see the following output:
56 |
57 | ```bash
58 | This will run even if panic occurs
59 | panic: Panic in main function
60 |
61 | goroutine 1 [running]:
62 | main.main()
63 | /path/to/your-repository/go_sample_examples/027_panic_and_defer/006_p
64 | anic_with_defer/006_panic_with_defer.go:12 +0x59
65 | exit status 2
66 | ```
--------------------------------------------------------------------------------
/026_sorting/009_sorting_a_map_by_values/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Sorting a Map by Values
2 |
3 | This repository demonstrates how to sort a map by its values in Go. It showcases how to convert a map into a slice of key-value pairs, sort the slice by the values, and then iterate over the sorted list to print the results.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers sorting a Go map by its values.
9 | - The map contains key-value pairs of names and ages, which are sorted by their values (ages).
10 | - It demonstrates how to use `sort.Slice` to sort the slice of key-value pairs by their values in ascending order.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```golang
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sort"
21 | )
22 |
23 | func main() {
24 |
25 | // Show how to sort a map by its values
26 |
27 | ages := map[string]int{
28 | "Alice": 25,
29 | "Charlie": 20,
30 | "Bob": 30,
31 | }
32 |
33 | type kv struct {
34 | Key string
35 | Value int
36 | }
37 |
38 | var sortedAges []kv
39 | for k, v := range ages {
40 | sortedAges = append(sortedAges, kv{k, v})
41 | }
42 |
43 | sort.Slice(sortedAges, func(i, j int) bool {
44 | return sortedAges[i].Value < sortedAges[j].Value
45 | })
46 |
47 | fmt.Println("Sorted by values:")
48 | for _, kv := range sortedAges {
49 | fmt.Println(kv.Key, kv.Value)
50 | }
51 | }
52 | ```
53 |
54 | ### 🏃 How to Run
55 |
56 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
57 | 2. Clone this repository:
58 |
59 | ```bash
60 | git clone https://github.com/Rapter1990/go_sample_examples.git
61 | ```
62 |
63 | 3. Navigate to the `009_sorting_a_map_by_values` directory:
64 |
65 | ```bash
66 | cd go_sample_examples/026_sorting/009_sorting_a_map_by_values
67 | ```
68 |
69 | 4. Run the Go program:
70 |
71 | ```bash
72 | go run main.go
73 | ```
74 |
75 | ### 📦 Output
76 |
77 | When you run the program, the output will display the map entries sorted by their values:
78 |
79 | ```bash
80 | Sorted by values:
81 | Charlie 20
82 | Alice 25
83 | Bob 30
84 | ```
--------------------------------------------------------------------------------
/026_sorting/010_concurrent_sorting_with_goroutines/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Concurrent Sorting with Goroutines
2 |
3 | This repository demonstrates how to perform concurrent sorting in Go using goroutines. It showcases how to use goroutines and `sync.WaitGroup` to sort multiple slices concurrently.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers concurrent sorting of slices in Go using goroutines.
9 | - It includes sorting multiple slices concurrently using the `sort.Ints` function and a `sync.WaitGroup` to synchronize the goroutines.
10 | - This example demonstrates the power of concurrency in Go for improving performance in multi-threaded environments.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```golang
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sort"
21 | "sync"
22 | )
23 |
24 | func sortSlice(slice []int, wg *sync.WaitGroup) {
25 | defer wg.Done()
26 | sort.Ints(slice)
27 | fmt.Println("Sorted slice:", slice)
28 | }
29 |
30 | func main() {
31 |
32 | // Use goroutines to sort multiple slices concurrently
33 |
34 | var wg sync.WaitGroup
35 |
36 | slices := [][]int{
37 | {3, 2, 1},
38 | {6, 5, 4},
39 | {9, 8, 7},
40 | }
41 |
42 | for _, slice := range slices {
43 | wg.Add(1)
44 | go sortSlice(slice, &wg)
45 | }
46 |
47 | wg.Wait()
48 | fmt.Println("All slices sorted")
49 | }
50 | ```
51 |
52 | ### 🏃 How to Run
53 |
54 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
55 | 2. Clone this repository:
56 |
57 | ```bash
58 | git clone https://github.com/Rapter1990/go_sample_examples.git
59 | ```
60 |
61 | 3. Navigate to the `010_concurrent_sorting_with_goroutines` directory:
62 |
63 | ```bash
64 | cd go_sample_examples/026_sorting/010_concurrent_sorting_with_goroutines
65 | ```
66 |
67 | 4. Run the Go program:
68 |
69 | ```bash
70 | go run main.go
71 | ```
72 |
73 | ### 📦 Output
74 |
75 | When you run the program, you should see output like the following:
76 |
77 | ```bash
78 | Sorted slice: [7 8 9]
79 | Sorted slice: [1 2 3]
80 | Sorted slice: [4 5 6]
81 | All slices sorted
82 | ```
--------------------------------------------------------------------------------
/026_sorting/007_sorting_with_custom_comparator_function/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Sorting with Custom Comparator Function
2 |
3 | This repository demonstrates how to sort a slice of structs using a custom comparator function in Go. It showcases how to use Go's `sort.Slice` function to sort a collection based on a user-defined condition, providing greater flexibility for sorting complex data structures.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers sorting a slice of structs using a custom comparator in Go.
9 | - It uses the `sort.Slice` function to sort a slice of `Person3` structs by the length of their `Name` field.
10 | - This approach can be adapted to sort slices based on any criteria.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```golang
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sort"
21 | )
22 |
23 | type Person3 struct {
24 | Name string
25 | Age int
26 | }
27 |
28 | func main() {
29 |
30 | // Sort a slice of structs with a custom comparator, which provides greater flexibility
31 |
32 | people := []Person3{
33 | {"Alice", 25},
34 | {"Bob", 30},
35 | {"Charlie", 20},
36 | }
37 |
38 | // Custom sort by Name length
39 | sort.Slice(people, func(i, j int) bool {
40 | return len(people[i].Name) < len(people[j].Name)
41 | })
42 |
43 | fmt.Println("Sorted by name length:", people)
44 | }
45 | ```
46 |
47 | ### 🏃 How to Run
48 |
49 | 1. Ensure you have Go installed. If not, download it from [here](https://golang.org/dl/).
50 | 2. Clone this repository:
51 |
52 | ```bash
53 | git clone https://github.com/Rapter1990/go_sample_examples.git
54 | ```
55 |
56 | 3. Navigate to the `007_sorting_with_custom_comparator_function` directory:
57 |
58 | ```bash
59 | cd go_sample_examples/026_sorting/007_sorting_with_custom_comparator_function
60 | ```
61 |
62 | 4. Run the Go program:
63 |
64 | ```bash
65 | go run main.go
66 | ```
67 |
68 | ### 📦 Output
69 |
70 | When you run the program, the output will display the `Person3` structs sorted by the length of their names:
71 |
72 | ```bash
73 | Sorted by name length: [{Bob 30} {Alice 25} {Charlie 20}]
74 | ```
--------------------------------------------------------------------------------
/025_atomic_counters/001_basic_atomic_counter_using_sync_atomic/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Basic Atomic Counter
2 |
3 | This repository demonstrates how to use an atomic counter in Go to safely increment and retrieve values across multiple goroutines using the `sync/atomic` package. It showcases concurrency control with atomic operations, ensuring thread-safe updates to shared variables.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the use of the `sync/atomic` package to create a thread-safe counter.
9 | - It shows how to increment a shared variable concurrently from multiple goroutines without data races.
10 | - The example uses a `WaitGroup` to ensure all goroutines finish before printing the final counter value.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sync"
21 | "sync/atomic"
22 | )
23 |
24 | func main() {
25 |
26 | // Basic Atomic Counter Using sync/atomic
27 | // Use an atomic counter to increment and retrieve values safely across multiple goroutines
28 |
29 | var counter int32 // Shared counter variable
30 | var wg sync.WaitGroup
31 |
32 | for i := 0; i < 5; i++ {
33 | wg.Add(1)
34 | go func() {
35 | for j := 0; j < 1000; j++ {
36 | atomic.AddInt32(&counter, 1) // Atomically increment the counter
37 | }
38 | wg.Done()
39 | }()
40 | }
41 |
42 | wg.Wait()
43 | fmt.Println("Final Counter:", counter)
44 | }
45 | ```
46 |
47 | ### 🏃 How to Run
48 |
49 | 1. Ensure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
50 | 2. Clone this repository:
51 |
52 | ```bash
53 | git clone https://github.com/Rapter1990/go_sample_examples.git
54 | ```
55 |
56 | 3. Navigate to the **025_atomic_counters/001_basic_atomic_counter_using_sync_atomic** directory:
57 |
58 | ```bash
59 | cd go_sample_examples/025_atomic_counters/001_basic_atomic_counter_using_sync_atomic
60 | ```
61 |
62 | 4. Run the Go program:
63 |
64 | ```bash
65 | go run main.go
66 | ```
67 |
68 | ### 📦 Output
69 |
70 | When you run the program, you should see an output similar to:
71 |
72 | ```bash
73 | Final Counter: 5000
74 | ```
--------------------------------------------------------------------------------
/020_timers/005_timer_with_select/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Timer with `select`
2 |
3 | This repository demonstrates how to use timers in Go with the `select` statement to handle multiple concurrent events. It showcases how to manage timers alongside other asynchronous events, providing a useful mechanism to handle concurrent operations and timeouts.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers how to use timers within a
select statement to wait for multiple events simultaneously in Go.
9 | - It includes a demonstration of handling multiple timers, firing based on time, and managing timeouts using
time.After.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "time"
20 | )
21 |
22 | func main() {
23 |
24 | // Timer with Select ( Use select to handle timers alongside other concurrent events )
25 | // You can use timers within a select statement to wait for multiple events simultaneously,
26 | // including the timer firing.
27 |
28 | timer1 := time.NewTimer(2 * time.Second) // create timer in 2 seconds
29 | timer2 := time.NewTimer(4 * time.Second) // create timer in 4 seconds
30 |
31 | select {
32 | case <-timer1.C:
33 | fmt.Println("Timer 1 fired")
34 | case <-timer2.C:
35 | fmt.Println("Timer 2 fired")
36 | case <-time.After(3 * time.Second):
37 | fmt.Println("Timeout! No timer fired in 3 seconds.")
38 | }
39 | }
40 | ```
41 |
42 | ### 🏃 How to Run
43 |
44 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
45 | 2. Clone this repository:
46 |
47 | ```bash
48 | git clone https://github.com/Rapter1990/go_sample_examples.git
49 | ```
50 |
51 | 3. Navigate to the `005_timer_with_select` directory:
52 |
53 | ```bash
54 | cd go_sample_examples/020_timers/005_timer_with_select
55 | ```
56 |
57 | 4. Run the Go program:
58 |
59 | ```bash
60 | go run 005_timer_with_select.go
61 | ```
62 |
63 | ### 📦 Output
64 |
65 | When you run the program, you should see one of the following outputs based on the timing of events:
66 |
67 | ```bash
68 | Timer 1 fired
69 | ```
--------------------------------------------------------------------------------
/023_waitgroup/002_waitGroup_with_anonymous_functions/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - WaitGroup with Anonymous Functions
2 |
3 | This repository demonstrates how to use a Go WaitGroup in conjunction with anonymous functions to synchronize multiple goroutines. It showcases how to launch goroutines with anonymous functions and wait for their completion using a `sync.WaitGroup`.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example demonstrates the use of WaitGroups with anonymous functions in Go.
9 | - It covers launching multiple goroutines, each using an anonymous function to simulate a task, and synchronizing their completion using a `sync.WaitGroup`.
10 | - The example shows how to pass arguments to anonymous functions within goroutines.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sync"
21 | )
22 |
23 | func main() {
24 |
25 | // WaitGroup with Anonymous Functions
26 | // Demonstrates using a WaitGroup with an anonymous function
27 |
28 | var wg sync.WaitGroup
29 | n := 5
30 |
31 | for i := 1; i <= n; i++ {
32 | wg.Add(1)
33 | go func(id int) {
34 | defer wg.Done()
35 | fmt.Printf("Worker %d is processing\n", id)
36 | }(i)
37 | }
38 |
39 | // Wait for all workers to finish
40 | wg.Wait()
41 | fmt.Println("All workers completed.")
42 | }
43 | ```
44 |
45 | ### 🏃 How to Run
46 |
47 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
48 | 2. Clone this repository:
49 |
50 | ```bash
51 | git clone https://github.com/Rapter1990/go_sample_examples.git
52 | ```
53 |
54 | 3. Navigate to the `023_waitgroup` directory:
55 |
56 | ```bash
57 | cd go_sample_examples/023_waitgroup/002_waitGroup_with_anonymous_functions
58 | ```
59 |
60 | 4. Run the Go program:
61 |
62 | ```bash
63 | go run 002_waitGroup_with_anonymous_functions.go
64 | ```
65 |
66 | ### 📦 Output
67 |
68 | When you run the program, you should see the following output:
69 |
70 | ```bash
71 | Worker 3 is processing
72 | Worker 2 is processing
73 | Worker 5 is processing
74 | Worker 4 is processing
75 | Worker 1 is processing
76 | All workers completed.
77 | ```
--------------------------------------------------------------------------------
/018_closing_channel/01_basic_channel_closing/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Closing Channels
2 |
3 | This repository demonstrates the concept of closing channels in Go. It shows how to close a channel after sending all values and how to use a `range` loop to receive values until the channel is closed.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers basic channel closing operations in Go.
9 | - It explains how to close a channel after sending all values and how to handle channel closure during value reception using a range loop.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import "fmt"
18 |
19 | func main() {
20 |
21 | // Basic Channel Closing
22 | // In this example, the channel is closed using close(ch) after all values are sent.
23 | // The range loop is used to receive values until the channel is closed.
24 | // Once the channel is closed, the loop automatically exits.
25 |
26 | ch := make(chan int)
27 |
28 | go func() {
29 | for i := 0; i < 5; i++ {
30 | ch <- i
31 | }
32 | close(ch) // Close the channel after sending all values
33 | }()
34 |
35 | // Receiving values until the channel is closed
36 | for value := range ch {
37 | fmt.Println("Received:", value)
38 | }
39 |
40 | fmt.Println("Channel closed, no more data.")
41 | }
42 | ```
43 |
44 | ### 🏃 How to Run
45 |
46 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
47 | 2. Clone this repository:
48 |
49 | ```bash
50 | git clone https://github.com/Rapter1990/go_sample_examples.git
51 | ```
52 |
53 | 3. Navigate to the `018_closing_channel/01_basic_channel_closing` directory:
54 |
55 | ```bash
56 | cd go_sample_examples/018_closing_channel/01_basic_channel_closing
57 | ```
58 |
59 | 4. Run the Go program:
60 |
61 | ```bash
62 | go run 01_basic_channel_closing.go
63 | ```
64 |
65 | ### 📦 Output
66 |
67 | When you run the program, you should see the following output:
68 |
69 | ```bash
70 | Received: 0
71 | Received: 1
72 | Received: 2
73 | Received: 3
74 | Received: 4
75 | Channel closed, no more data.
76 | ```
77 |
--------------------------------------------------------------------------------
/018_closing_channel/04_sending_a_signal_with_a_closed_channel/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Sending a Signal with a Closed Channel
2 |
3 | This repository demonstrates how to use a closed channel as a signal in Go. It shows how a goroutine can signal the completion of a task by closing a channel, and how the main function can wait for this signal to proceed.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example demonstrates how to use a channel to signal the completion of a task by closing the channel.
9 | - The main function waits for the task goroutine to complete by reading from the closed channel, which signals that the task is done.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "time"
20 | )
21 |
22 | func task(ch chan bool) {
23 | time.Sleep(2 * time.Second)
24 | close(ch) // Close the channel to send a signal
25 | }
26 |
27 | func main() {
28 |
29 | // Sending a Signal with a Closed Channel
30 |
31 | // A channel is used as a signal. The task goroutine performs some work and then closes the channel to signal that the task is complete.
32 | // The main function waits for the signal by reading from the channel
33 |
34 | signal := make(chan bool)
35 |
36 | go task(signal)
37 |
38 | fmt.Println("Waiting for task to complete...")
39 |
40 | // Wait for the signal
41 | <-signal
42 |
43 | fmt.Println("Task completed.")
44 | }
45 | ```
46 |
47 | ### 🏃 How to Run
48 |
49 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
50 | 2. Clone this repository:
51 |
52 | ```bash
53 | git clone https://github.com/Rapter1990/go_sample_examples.git
54 | ```
55 |
56 | 3. Navigate to the `018_closing_channel/04_sending_a_signal_with_a_closed_channel` directory:
57 |
58 | ```bash
59 | cd go_sample_examples/018_closing_channel/04_sending_a_signal_with_a_closed_channel
60 | ```
61 |
62 | 4. Run the Go program:
63 |
64 | ```bash
65 | go run 04_sending_a_signal_with_a_closed_channel.go
66 | ```
67 |
68 | ### 📦 Output
69 |
70 | When you run the program, you should see the following output:
71 |
72 | ```bash
73 | Waiting for task to complete...
74 | Task completed.
75 | ```
--------------------------------------------------------------------------------
/024_rate_limiter/001_basic_rate_limiter/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Basic Rate Limiter
2 |
3 | This repository demonstrates a basic rate limiter implementation in Go. It shows how to control the rate of request processing using Go's `time.Tick` function.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers basic rate limiting techniques in Go.
9 | - It includes a simple implementation to limit the processing of requests at a fixed interval.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "time"
20 | )
21 |
22 | func main() {
23 |
24 | // Basic Rate Limiting Using time.Tick
25 | // Show how to limit the processing of requests to one every 200 milliseconds.
26 |
27 | requests := make(chan int, 5)
28 |
29 | for i := 1; i <= 5; i++ {
30 | requests <- i
31 | }
32 | close(requests)
33 |
34 | // Create a rate limiter that ticks every 200 milliseconds
35 | limiter := time.Tick(200 * time.Millisecond)
36 |
37 | for req := range requests {
38 | <-limiter // Wait for the next tick
39 | fmt.Println("Request", req, "processed at", time.Now())
40 | }
41 |
42 | }
43 | ```
44 |
45 | ### 🏃 How to Run
46 |
47 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
48 | 2. Clone this repository:
49 |
50 | ```bash
51 | git clone https://github.com/Rapter1990/go_sample_examples.git
52 | ```
53 |
54 | 3. Navigate to the 024_rate_limiter/001_basic_rate_limiter directory:
55 |
56 | ```bash
57 | cd go_sample_examples/024_rate_limiter/001_basic_rate_limiter
58 | ```
59 |
60 | 4. Run the Go program:
61 |
62 | ```bash
63 | go run main.go
64 | ```
65 |
66 | ### 📦 Output
67 |
68 | When you run the program, you should see the following output:
69 |
70 | ```
71 | Request 1 processed at 2024-09-15 17:49:27.3630742 +0300 +03 m=+0.200725901
72 | Request 2 processed at 2024-09-15 17:49:27.5638677 +0300 +03 m=+0.401519401
73 | Request 3 processed at 2024-09-15 17:49:27.7631892 +0300 +03 m=+0.600840901
74 | Request 4 processed at 2024-09-15 17:49:27.9639358 +0300 +03 m=+0.801587501
75 | Request 5 processed at 2024-09-15 17:49:28.1636925 +0300 +03 m=+1.001344201
76 | ```
--------------------------------------------------------------------------------
/030_json/002_basic_decoding_json/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Basic JSON Decoding
2 |
3 | This repository demonstrates how to decode JSON strings into Go structs using Go's standard library package `encoding/json`. It showcases how to unmarshal JSON data into Go structures and perform operations on the decoded data.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers basic JSON decoding using Go structs and the `json.Unmarshal` function.
9 | - It demonstrates how to convert a JSON string into a Go struct, handle errors during decoding, and marshal the struct back into a formatted JSON string.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "encoding/json"
19 | "fmt"
20 | )
21 |
22 | type Person1 struct {
23 | Name string
24 | Age int
25 | Country string
26 | }
27 |
28 | func main() {
29 |
30 | // This example demonstrates how to convert a JSON string into a Go struct using json.Unmarshal
31 |
32 | jsonString := `{"Name":"John","Age":30,"Country":"USA"}`
33 |
34 | var person Person1
35 |
36 | err := json.Unmarshal([]byte(jsonString), &person)
37 | if err != nil {
38 | fmt.Println("Error decoding JSON:", err)
39 | return
40 | }
41 |
42 | // Marshal the struct back to JSON format
43 | jsonOutput, err := json.MarshalIndent(person, "", " ")
44 | if err != nil {
45 | fmt.Println("Error encoding JSON:", err)
46 | return
47 | }
48 |
49 | fmt.Println(string(jsonOutput))
50 | }
51 | ```
52 |
53 | ### 🏃 How to Run
54 |
55 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
56 | 2. Clone this repository:
57 |
58 | ```bash
59 | git clone https://github.com/Rapter1990/go_sample_examples.git
60 | ```
61 |
62 | 3. Navigate to the `002_basic_decoding_json` directory:
63 |
64 | ```bash
65 | cd go_sample_examples/030_json/002_basic_decoding_json
66 | ```
67 |
68 | 4. Run the Go program:
69 |
70 | ```bash
71 | go run 002_basic_decoding_json.go
72 | ```
73 |
74 | ### 📦 Output
75 |
76 | When you run the program, you should see the following output:
77 |
78 | ```json
79 | {
80 | "Name": "John",
81 | "Age": 30,
82 | "Country": "USA"
83 | }
84 | ```
--------------------------------------------------------------------------------
/030_json/008_decoding_json_into_a_map_string_interface/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Decoding JSON into a Map
2 |
3 | This repository demonstrates how to decode JSON data into a `map[string]interface{}` in Go. This approach is useful when the structure of the JSON data is not known in advance or when working with dynamic JSON data.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example shows how to handle JSON data when the structure is unknown or dynamic.
9 | - It demonstrates decoding JSON into a `map[string]interface{}` and accessing the fields from the resulting map.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "encoding/json"
19 | "fmt"
20 | )
21 |
22 | func main() {
23 |
24 | // This example demonstrates how to decode JSON data into a map[string]interface{}.
25 | // This is useful for working with JSON data when the structure isn't known in advance
26 |
27 | jsonString := `{"Name":"John","Age":30,"Country":"USA"}`
28 |
29 | var result map[string]interface{}
30 |
31 | err := json.Unmarshal([]byte(jsonString), &result)
32 | if err != nil {
33 | fmt.Println("Error decoding JSON into map:", err)
34 | return
35 | }
36 |
37 | fmt.Println("Decoded map:", result)
38 |
39 | // Accessing fields
40 | fmt.Println("Name:", result["Name"])
41 | fmt.Println("Age:", result["Age"])
42 | fmt.Println("Country:", result["Country"])
43 |
44 | }
45 | ```
46 |
47 | ### 🏃 How to Run
48 |
49 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
50 | 2. Clone this repository:
51 |
52 | ```bash
53 | git clone https://github.com/Rapter1990/go_sample_examples.git
54 | ```
55 |
56 | 3. Navigate to the `008_decoding_json_into_a_map_string_interface` directory:
57 |
58 | ```bash
59 | cd go_sample_examples/030_json/008_decoding_json_into_a_map_string_interface
60 | ```
61 |
62 | 4. Run the Go program:
63 |
64 | ```bash
65 | go run 008_decoding_json_into_a_map_string_interface.go
66 | ```
67 |
68 | ### 📦 Output
69 |
70 | When you run the program, you should see the following output:
71 |
72 | ```
73 | Decoded map: map[Age:30 Country:USA Name:John]
74 | Name: John
75 | Age: 30
76 | Country: USA
77 | ```
--------------------------------------------------------------------------------
/024_rate_limiter/003_custom_rate_limiter_using_time_after/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Custom Rate Limiter Using `time.After`
2 |
3 | This repository demonstrates a custom rate limiter implementation in Go using `time.After`. It showcases a flexible approach to rate-limit each request individually.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers custom rate limiting techniques using `time.After` in Go.
9 | - It includes an implementation where each request is delayed by a specified time interval before processing.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "time"
20 | )
21 |
22 | func main() {
23 |
24 | // Custom Rate Limiting Using time.After
25 | // Show a more flexible approach where each request is rate-limited individually.
26 |
27 | requests := make(chan int, 5)
28 |
29 | for i := 1; i <= 5; i++ {
30 | requests <- i
31 | }
32 | close(requests)
33 |
34 | for req := range requests {
35 | // Delay processing each request by 200 milliseconds
36 | time.Sleep(200 * time.Millisecond)
37 | fmt.Println("Request", req, "processed at", time.Now())
38 | }
39 |
40 | }
41 | ```
42 |
43 | ### 🏃 How to Run
44 |
45 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
46 | 2. Clone this repository:
47 |
48 | ```bash
49 | git clone https://github.com/Rapter1990/go_sample_examples.git
50 | ```
51 |
52 | 3. Navigate to the 024_rate_limiter/003_custom_rate_limiter_using_time_after directory:
53 |
54 | ```bash
55 | cd go_sample_examples/024_rate_limiter/003_custom_rate_limiter_using_time_after
56 | ```
57 |
58 | 4. Run the Go program:
59 |
60 | ```bash
61 | go run main.go
62 | ```
63 |
64 | ### 📦 Output
65 |
66 | When you run the program, you should see output similar to:
67 |
68 | ```
69 | Request 1 processed at 2024-09-15 17:55:27.0855462 +0300 +03 m=+0.201428901
70 | Request 2 processed at 2024-09-15 17:55:27.3143205 +0300 +03 m=+0.430203201
71 | Request 3 processed at 2024-09-15 17:55:27.5147307 +0300 +03 m=+0.630613401
72 | Request 4 processed at 2024-09-15 17:55:27.7153769 +0300 +03 m=+0.831259601
73 | Request 5 processed at 2024-09-15 17:55:27.9158934 +0300 +03 m=+1.031776101
74 | ```
--------------------------------------------------------------------------------
/023_waitgroup/001_basic_waitgroup/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - WaitGroup
2 |
3 | This repository demonstrates how to use WaitGroups in Go to synchronize multiple goroutines. A WaitGroup helps wait for a collection of goroutines to complete their tasks before the main program continues execution or terminates.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the basic usage of WaitGroups in Go.
9 | - It shows how to start multiple goroutines and wait for their completion using the `sync.WaitGroup`.
10 | - The example includes a simple worker function that simulates a task and demonstrates how to use WaitGroups to synchronize the completion of multiple workers.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sync"
21 | )
22 |
23 | func worker(id int, wg *sync.WaitGroup) {
24 | defer wg.Done()
25 | fmt.Printf("Worker %d starting\n", id)
26 | // Simulate some work with sleep
27 | // time.Sleep(time.Second)
28 | fmt.Printf("Worker %d done\n", id)
29 | }
30 |
31 | func main() {
32 |
33 | // we use a WaitGroup to wait for a set of goroutines to complete their execution before the program exits
34 |
35 | // Basic WaitGroup Example
36 |
37 | var wg sync.WaitGroup
38 |
39 | for i := 1; i <= 3; i++ {
40 | wg.Add(1)
41 | go worker(i, &wg)
42 | }
43 |
44 | // Wait for all workers to finish
45 | wg.Wait()
46 | fmt.Println("All workers completed.")
47 | }
48 | ```
49 |
50 | ### 🏃 How to Run
51 |
52 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
53 | 2. Clone this repository:
54 |
55 | ```bash
56 | git clone https://github.com/Rapter1990/go_sample_examples.git
57 | ```
58 |
59 | 3. Navigate to the `023_waitgroup` directory:
60 |
61 | ```bash
62 | cd go_sample_examples/023_waitgroup/001_basic_waitgroup
63 | ```
64 |
65 | 4. Run the Go program:
66 |
67 | ```bash
68 | go run 001_basic_waitgroup.go
69 | ```
70 |
71 | ### 📦 Output
72 |
73 | When you run the program, you should see the following output:
74 |
75 | ```bash
76 | Worker 3 starting
77 | Worker 3 done
78 | Worker 1 starting
79 | Worker 1 done
80 | Worker 2 starting
81 | Worker 2 done
82 | All workers completed.
83 | ```
--------------------------------------------------------------------------------
/019_range_over_channel/003_buffered_channels_with_range/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Buffered Channels with Range
2 |
3 | This repository demonstrates how to use buffered channels with the `range` keyword in Go. It showcases how to control the flow of data using buffered channels, which allow Goroutines to send values into a channel without requiring an immediate receiver. The `range` construct is used to receive and process data from the channel until it is closed.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the basics of buffered channels and their usage in Go.
9 | - It demonstrates how to send data to a buffered channel and how to use the `range` keyword to receive data until the channel is closed.
10 | - Buffered channels are useful when you need to handle multiple values in a non-blocking way, allowing for better flow control in concurrent programs.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | )
21 |
22 | func main() {
23 |
24 | // Buffered Channels with Range
25 | // Combine buffered channels with range to control the flow of data
26 |
27 | ch := make(chan int, 3) // Create a buffered channel
28 |
29 | // Send values to the buffered channel
30 | ch <- 1
31 | ch <- 2
32 | ch <- 3
33 |
34 | close(ch) // Close the channel
35 |
36 | // Receive values using range
37 | for value := range ch {
38 | fmt.Println("Received:", value)
39 | }
40 |
41 | fmt.Println("Channel closed, no more data.")
42 | }
43 | ```
44 |
45 | ### 🏃 How to Run
46 |
47 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
48 | 2. Clone this repository:
49 |
50 | ```bash
51 | git clone https://github.com/Rapter1990/go_sample_examples.git
52 | ```
53 |
54 | 3. Navigate to the `019_range_over_channel/003_buffered_channels_with_range` directory:
55 |
56 | ```bash
57 | cd go_sample_examples/019_range_over_channel/003_buffered_channels_with_range
58 | ```
59 |
60 | 4. Run the Go program:
61 |
62 | ```bash
63 | go run main.go
64 | ```
65 |
66 | ### 📦 Output
67 |
68 | When you run the program, you should see the following output:
69 |
70 | ```
71 | Received: 1
72 | Received: 2
73 | Received: 3
74 | Channel closed, no more data.
75 | ```
--------------------------------------------------------------------------------
/021_tickers/02_stop_ticker/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Stop Ticker
2 |
3 | This repository demonstrates how to stop a ticker in Go. Tickers are used to trigger actions at regular intervals, but stopping them when no longer needed is crucial to avoid unnecessary resource consumption.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers how to stop a ticker in Go.
9 | - It demonstrates creating a ticker, running it for a limited time, and stopping it gracefully to avoid resource waste.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "time"
20 | )
21 |
22 | func main() {
23 |
24 | // Stopping a Ticker
25 | // Stopping a ticker is crucial when you no longer need it to avoid unnecessary resource consumption
26 |
27 | // Create a ticker that ticks every 500 milliseconds
28 | ticker := time.NewTicker(500 * time.Millisecond)
29 |
30 | // Create a channel to signal the stop of the ticker
31 | done := make(chan bool)
32 |
33 | go func() {
34 | time.Sleep(2 * time.Second) // Let the ticker run for 2 seconds
35 | ticker.Stop()
36 | done <- true
37 | }()
38 |
39 | // Print tick events until the ticker is stopped
40 | go func() {
41 | for t := range ticker.C {
42 | fmt.Println("Tick at", t)
43 | }
44 | }()
45 |
46 | <-done
47 | fmt.Println("Ticker stopped.")
48 | }
49 | ```
50 |
51 | ### 🏃 How to Run
52 |
53 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
54 | 2. Clone this repository:
55 |
56 | ```bash
57 | git clone https://github.com/Rapter1990/go_sample_examples.git
58 | ```
59 |
60 | 3. Navigate to the `021_tickers/02_stop_ticker` directory:
61 |
62 | ```bash
63 | cd go_sample_examples/021_tickers/02_stop_ticker
64 | ```
65 |
66 | 4. Run the Go program:
67 |
68 | ```bash
69 | go run main.go
70 | ```
71 |
72 | ### 📦 Output
73 |
74 | When you run the program, you should see the following output, where the ticker prints a message every 500 milliseconds and stops after 2 seconds:
75 |
76 | ```bash
77 | Tick at 2024-09-14 11:38:40.5725702 +0300 +03 m=+0.500607401
78 | Tick at 2024-09-14 11:38:41.0725702 +0300 +03 m=+1.000607401
79 | Tick at 2024-09-14 11:38:41.5725702 +0300 +03 m=+1.500607401
80 | Ticker stopped.
81 | ```
--------------------------------------------------------------------------------
/021_tickers/03_ticker_with_select/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Ticker with Select
2 |
3 | This repository demonstrates how to use a ticker with a `select` statement in Go. Tickers trigger actions at regular intervals, and combining them with `select` allows you to handle multiple concurrent events efficiently.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers how to use a ticker inside a `select` statement to manage multiple concurrent events.
9 | - It demonstrates starting a ticker, listening for tick events, and stopping the ticker after receiving a stop signal through a channel.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "time"
20 | )
21 |
22 | func main() {
23 |
24 | // Using Ticker with Select
25 | // Use a ticker inside a select statement to manage multiple concurrent events
26 |
27 | ticker := time.NewTicker(1 * time.Second)
28 | stop := make(chan bool)
29 |
30 | go func() {
31 | time.Sleep(3 * time.Second)
32 | stop <- true
33 | }()
34 |
35 | for {
36 | select {
37 | case t := <-ticker.C:
38 | fmt.Println("Tick at", t)
39 | case <-stop:
40 | fmt.Println("Stop signal received.")
41 | ticker.Stop()
42 | return
43 | }
44 | }
45 |
46 | // The select statement listens for ticks and a stop signal
47 | // When the stop channel receives a signal, the ticker is stopped, and the program exits the loop
48 |
49 | }
50 | ```
51 |
52 | ### 🏃 How to Run
53 |
54 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
55 | 2. Clone this repository:
56 |
57 | ```bash
58 | git clone https://github.com/Rapter1990/go_sample_examples.git
59 | ```
60 |
61 | 3. Navigate to the `021_tickers/03_ticker_with_select` directory:
62 |
63 | ```bash
64 | cd go_sample_examples/021_tickers/03_ticker_with_select
65 | ```
66 |
67 | 4. Run the Go program:
68 |
69 | ```bash
70 | go run main.go
71 | ```
72 |
73 | ### 📦 Output
74 |
75 | When you run the program, you should see the following output:
76 |
77 | ```bash
78 | Tick at 2024-09-14 11:41:28.3952744 +0300 +03 m=+1.000525401
79 | Tick at 2024-09-14 11:41:29.3952744 +0300 +03 m=+2.000525401
80 | Tick at 2024-09-14 11:41:30.3952744 +0300 +03 m=+3.000525401
81 | Stop signal received.
82 | ```
--------------------------------------------------------------------------------
/018_closing_channel/02_detecting_closed_channel/README.md:
--------------------------------------------------------------------------------
1 | Here is the `README.md` for the provided code in the same format as the previous example:
2 |
3 | # Go Sample Example - Detecting Closed Channels
4 |
5 | This repository demonstrates how to detect when a channel is closed in Go. It uses the `value, ok := <-ch` pattern to check if the channel is closed and gracefully exits the loop when no more data is available.
6 |
7 | ## 📖 Information
8 |
9 |
10 | - This example covers detecting the closure of a channel in Go.
11 | - It uses the boolean `ok` value from channel operations to identify when a channel is closed, allowing the program to handle it appropriately.
12 |
13 |
14 | ## 💻 Code Example
15 |
16 | ```go
17 | package main
18 |
19 | import "fmt"
20 |
21 | func main() {
22 |
23 | // Detecting Closed Channel
24 | // value, ok := <-ch is used to check if the channel is closed.
25 | // The ok will be false when the channel is closed, and the loop breaks.
26 |
27 | ch := make(chan int)
28 | done := make(chan bool)
29 |
30 | go func() {
31 | for i := 0; i < 5; i++ {
32 | ch <- i
33 | }
34 | close(ch) // Close the channel after sending all values
35 | done <- true
36 | }()
37 |
38 | // Continuously receive until done is true
39 | for {
40 | value, ok := <-ch
41 | if !ok {
42 | fmt.Println("Channel is closed.")
43 | break
44 | }
45 | fmt.Println("Received:", value)
46 | }
47 | <-done // Ensure the goroutine has finished
48 | }
49 | ```
50 |
51 | ### 🏃 How to Run
52 |
53 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
54 | 2. Clone this repository:
55 |
56 | ```bash
57 | git clone https://github.com/Rapter1990/go_sample_examples.git
58 | ```
59 |
60 | 3. Navigate to the `018_closing_channel/02_detecting_closed_channel` directory:
61 |
62 | ```bash
63 | cd go_sample_examples/018_closing_channel/02_detecting_closed_channel
64 | ```
65 |
66 | 4. Run the Go program:
67 |
68 | ```bash
69 | go run 02_detecting_closed_channel.go
70 | ```
71 |
72 | ### 📦 Output
73 |
74 | When you run the program, you should see the following output:
75 |
76 | ```bash
77 | Received: 0
78 | Received: 1
79 | Received: 2
80 | Received: 3
81 | Received: 4
82 | Channel is closed.
83 | ```
--------------------------------------------------------------------------------
/024_rate_limiter/005_rate_limiter_with_time_newticker/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Rate Limiter with `time.NewTicker`
2 |
3 | This repository demonstrates how to implement rate limiting in Go using `time.NewTicker`. It shows how to use a ticker to control the rate at which requests are processed.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers implementing rate limiting using `time.NewTicker` in Go.
9 | - It includes techniques for controlling the processing rate of requests with a ticker.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "time"
20 | )
21 |
22 | func main() {
23 |
24 | // Rate Limiting Using time.NewTicker
25 | // Use time.NewTicker for more control over the ticker's lifecycle
26 |
27 | requests := make(chan int, 5)
28 |
29 | for i := 1; i <= 5; i++ {
30 | requests <- i
31 | }
32 | close(requests)
33 |
34 | // Create a ticker that ticks every 200 milliseconds
35 | ticker := time.NewTicker(200 * time.Millisecond)
36 | defer ticker.Stop()
37 |
38 | for req := range requests {
39 | <-ticker.C // Wait for the next tick
40 | fmt.Println("Request", req, "processed at", time.Now())
41 | }
42 |
43 | }
44 | ```
45 |
46 | ### 🏃 How to Run
47 |
48 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
49 | 2. Clone this repository:
50 |
51 | ```bash
52 | git clone https://github.com/Rapter1990/go_sample_examples.git
53 | ```
54 |
55 | 3. Navigate to the 024_rate_limiter/005_rate_limiter_with_time_newticker directory:
56 |
57 | ```bash
58 | cd go_sample_examples/024_rate_limiter/005_rate_limiter_with_time_newticker
59 | ```
60 |
61 | 4. Run the Go program:
62 |
63 | ```bash
64 | go run main.go
65 | ```
66 |
67 | ### 📦 Output
68 |
69 | When you run the program, you should see output similar to:
70 |
71 | ```
72 | Request 1 processed at 2024-09-15 18:03:59.5443568 +0300 +03 m=+0.200915601
73 | Request 2 processed at 2024-09-15 18:03:59.7447692 +0300 +03 m=+0.401328001
74 | Request 3 processed at 2024-09-15 18:03:59.9442464 +0300 +03 m=+0.600805201
75 | Request 4 processed at 2024-09-15 18:04:00.1447645 +0300 +03 m=+0.801323301
76 | Request 5 processed at 2024-09-15 18:04:00.3447322 +0300 +03 m=+1.001291001
77 | ```
--------------------------------------------------------------------------------
/020_timers/002_stop_timer/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Stopping a Timer
2 |
3 | This repository demonstrates how to stop a timer in Go before it fires. It includes an example of creating a timer that can be stopped, preventing it from executing the intended action after a specified duration.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example shows how to stop a Go timer using the
Stop method before it fires.
9 | - If the timer is successfully stopped, the program will prevent the timer's action from executing, and the message indicating the timer has fired will not be printed.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "time"
20 | )
21 |
22 | func main() {
23 |
24 | // Stopping a Timer
25 | // You can stop a timer before it fires using the Stop method.
26 | // If the timer is stopped before it fires, the program will not receive any value from the timer's channel
27 |
28 | // Create a timer that will fire after 3 seconds
29 | timer := time.NewTimer(3 * time.Second)
30 |
31 | // Start a goroutine to stop the timer after 1 second
32 | go func() {
33 | time.Sleep(1 * time.Second)
34 | stop := timer.Stop()
35 | if stop {
36 | fmt.Println("Timer stopped before it fired.")
37 | }
38 | }()
39 |
40 | // Wait for the timer to fire
41 | <-timer.C
42 | fmt.Println("This will not be printed if the timer is stopped.")
43 | }
44 | ```
45 |
46 | ### 🏃 How to Run
47 |
48 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
49 | 2. Clone this repository:
50 |
51 | ```bash
52 | git clone https://github.com/Rapter1990/go_sample_examples.git
53 | ```
54 |
55 | 3. Navigate to the `001_stopping_timer` directory:
56 |
57 | ```bash
58 | cd go_sample_examples/020_timers/001_stopping_timer
59 | ```
60 |
61 | 4. Run the Go program:
62 |
63 | ```bash
64 | go run 001_stopping_timer.go
65 | ```
66 |
67 | ### 📦 Output
68 |
69 | When you run the program, you should see the following output:
70 |
71 | ```bash
72 | Timer stopped before it fired.
73 | ```
74 |
75 | If the timer is not stopped in time, the program will print:
76 |
77 | ```bash
78 | Timer stopped before it fired.
79 | fatal error: all goroutines are asleep - deadlock!
80 | ```
--------------------------------------------------------------------------------
/029_text_samples/002_loops_in_templates/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Loops in Templates
2 |
3 | This repository demonstrates how to use loops in Go's `text/template` package. It shows how to iterate over a collection of data and render each item in a template, providing dynamic content generation based on input data.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers basic loop constructs in Go templates using the `range` keyword.
9 | - It includes a demonstration of looping over a slice of structs to display tasks and their statuses.
10 | - Showcases how to render dynamic data in a structured format within templates.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "os"
21 | "text/template"
22 | )
23 |
24 | type Task struct {
25 | Title string
26 | Status string
27 | }
28 |
29 | type Person1 struct {
30 | Name string
31 | Tasks []Task
32 | }
33 |
34 | func main() {
35 |
36 | // This template uses range to loop over a slice of Task structs and list out each task with its status.
37 |
38 | person := Person1{
39 | Name: "Bob",
40 | Tasks: []Task{
41 | {"Task 1", "Completed"},
42 | {"Task 2", "Pending"},
43 | {"Task 3", "In Progress"},
44 | },
45 | }
46 |
47 | tpl := `{{.Name}}'s Tasks:
48 | {{range .Tasks}}- {{.Title}}: {{.Status}}
49 | {{end}}`
50 |
51 | t := template.Must(template.New("person").Parse(tpl))
52 |
53 | err := t.Execute(os.Stdout, person)
54 | if err != nil {
55 | fmt.Println("Error executing template:", err)
56 | }
57 | }
58 | ```
59 |
60 | ### 🏃 How to Run
61 |
62 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
63 | 2. Clone this repository:
64 |
65 | ```bash
66 | git clone https://github.com/Rapter1990/go_sample_examples.git
67 | ```
68 |
69 | 3. Navigate to the `029_text_samples/002_loops_in_templates` directory:
70 |
71 | ```bash
72 | cd go_sample_examples/029_text_samples/002_loops_in_templates
73 | ```
74 |
75 | 4. Run the Go program:
76 |
77 | ```bash
78 | go run 002_loops_in_templates.go
79 | ```
80 |
81 | ### 📦 Output
82 |
83 | When you run the program, you should see the following output:
84 |
85 | ```
86 | Bob's Tasks:
87 | - Task 1: Completed
88 | - Task 2: Pending
89 | - Task 3: In Progress
90 | ```
--------------------------------------------------------------------------------
/026_sorting/004_sorting_by_multiple_fields/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Sorting by Multiple Fields
2 |
3 | This repository demonstrates how to sort a slice of structs in Go by multiple fields using the built-in `sort.Slice` function. It provides an example of sorting by one field, and if the values are the same, sorting by a secondary field.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers sorting a slice of structs in Go by multiple fields.
9 | - It sorts a slice of `Person1` structs first by the `Age` field, and if two people have the same age, it sorts them by the `Name` field.
10 | - Sorting by multiple fields is a common task in Go, especially when you need to order records based on multiple criteria.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```golang
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sort"
21 | )
22 |
23 | // Define the Person1 struct with Name and Age fields
24 | type Person1 struct {
25 | Name string
26 | Age int
27 | }
28 |
29 | func main() {
30 |
31 | // Slice of Person1 structs to sort
32 | people := []Person1{
33 | {"Alice", 30},
34 | {"Bob", 25},
35 | {"Charlie", 30},
36 | {"Dave", 25},
37 | }
38 |
39 | // Sorting the slice first by Age, then by Name if Age is the same
40 | sort.Slice(people, func(i, j int) bool {
41 | if people[i].Age == people[j].Age {
42 | return people[i].Name < people[j].Name
43 | }
44 | return people[i].Age < people[j].Age
45 | })
46 |
47 | // Printing the sorted slice
48 | fmt.Println("Sorted by age and name:", people)
49 | }
50 | ```
51 |
52 | ### 🏃 How to Run
53 |
54 | 1. Ensure you have Go installed. If not, download it from [here](https://golang.org/dl/).
55 | 2. Clone this repository:
56 |
57 | ```bash
58 | git clone https://github.com/Rapter1990/go_sample_examples.git
59 | ```
60 |
61 | 3. Navigate to the `004_sorting_by_multiple_fields` directory:
62 |
63 | ```bash
64 | cd go_sample_examples/026_sorting/004_sorting_by_multiple_fields
65 | ```
66 |
67 | 4. Run the Go program:
68 |
69 | ```bash
70 | go run main.go
71 | ```
72 |
73 | ### 📦 Output
74 |
75 | When you run the program, the output will display the sorted slice of `Person1` structs by age and name:
76 |
77 | ```bash
78 | Sorted by age and name: [{Bob 25} {Dave 25} {Alice 30} {Charlie 30}]
79 | ```
--------------------------------------------------------------------------------
/021_tickers/05_ticker_with_limited_ticks/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Ticker with Limited Ticks
2 |
3 | This repository demonstrates how to use a ticker in Go with a set limit on the number of ticks. A ticker generates events at regular intervals, and this example shows how to stop the ticker after reaching a specified number of ticks.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers how to create and stop a ticker after a certain number of ticks.
9 | - It demonstrates how to set a maximum number of ticks before stopping the ticker.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "time"
20 | )
21 |
22 | func main() {
23 |
24 | // Ticker with Limited Ticks
25 | // Stop the ticker after a certain number of ticks
26 |
27 | // Create a ticker that ticks every 1 second
28 | ticker := time.NewTicker(1 * time.Second)
29 |
30 | // Create a counter for the number of ticks
31 | count := 0
32 | maxTicks := 5
33 |
34 | for t := range ticker.C {
35 | fmt.Println("Tick at", t)
36 | count++
37 | if count >= maxTicks {
38 | ticker.Stop()
39 | break
40 | }
41 | }
42 |
43 | fmt.Println("Ticker stopped after", maxTicks, "ticks.")
44 |
45 | // The ticker is set to stop after 5 ticks
46 | // The loop counts the ticks and stops the ticker once the limit is reached
47 | }
48 | ```
49 |
50 | ### 🏃 How to Run
51 |
52 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
53 | 2. Clone this repository:
54 |
55 | ```bash
56 | git clone https://github.com/Rapter1990/go_sample_examples.git
57 | ```
58 |
59 | 3. Navigate to the `021_tickers/05_ticker_with_limited_ticks` directory:
60 |
61 | ```bash
62 | cd go_sample_examples/021_tickers/05_ticker_with_limited_ticks
63 | ```
64 |
65 | 4. Run the Go program:
66 |
67 | ```bash
68 | go run main.go
69 | ```
70 |
71 | ### 📦 Output
72 |
73 | When you run the program, you should see the following output:
74 |
75 | ```bash
76 | Tick at 2024-09-14 11:48:18.9710563 +0300 +03 m=+1.000576301
77 | Tick at 2024-09-14 11:48:19.9710563 +0300 +03 m=+2.000576301
78 | Tick at 2024-09-14 11:48:20.9710563 +0300 +03 m=+3.000576301
79 | Tick at 2024-09-14 11:48:21.9710563 +0300 +03 m=+4.000576301
80 | Tick at 2024-09-14 11:48:22.9710563 +0300 +03 m=+5.000576301
81 | Ticker stopped after 5 ticks.
82 | ```
--------------------------------------------------------------------------------
/030_json/004_working_with_json_arrays/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Working with JSON Arrays
2 |
3 | This repository demonstrates how to work with JSON arrays in Go by decoding a JSON array into a slice of structs. It showcases how to handle and manipulate JSON arrays using Go's `encoding/json` package.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers how to decode JSON arrays into slices of structs in Go using the `json.Unmarshal` function.
9 | - It demonstrates how to work with JSON data representing multiple objects and then marshal it back to a formatted JSON string.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "encoding/json"
19 | "fmt"
20 | )
21 |
22 | type Person4 struct {
23 | Name string
24 | Age int
25 | Country string
26 | }
27 |
28 | func main() {
29 |
30 | // This example shows how to decode a JSON array into a slice of structs
31 |
32 | jsonString := `[{"Name":"John","Age":30,"Country":"USA"},{"Name":"Alice","Age":28,"Country":"Canada"}]`
33 |
34 | var people []Person4
35 |
36 | err := json.Unmarshal([]byte(jsonString), &people)
37 | if err != nil {
38 | fmt.Println("Error decoding JSON array:", err)
39 | return
40 | }
41 |
42 | // Marshal the struct back to JSON format
43 | jsonOutput, err := json.MarshalIndent(people, "", " ")
44 | if err != nil {
45 | fmt.Println("Error encoding JSON:", err)
46 | return
47 | }
48 |
49 | fmt.Println(string(jsonOutput))
50 |
51 | }
52 | ```
53 |
54 | ### 🏃 How to Run
55 |
56 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
57 | 2. Clone this repository:
58 |
59 | ```bash
60 | git clone https://github.com/Rapter1990/go_sample_examples.git
61 | ```
62 |
63 | 3. Navigate to the `004_working_with_json_arrays` directory:
64 |
65 | ```bash
66 | cd go_sample_examples/030_json/004_working_with_json_arrays
67 | ```
68 |
69 | 4. Run the Go program:
70 |
71 | ```bash
72 | go run 004_working_with_json_arrays.go
73 | ```
74 |
75 | ### 📦 Output
76 |
77 | When you run the program, you should see the following output:
78 |
79 | ```json
80 | [
81 | {
82 | "Name": "John",
83 | "Age": 30,
84 | "Country": "USA"
85 | },
86 | {
87 | "Name": "Alice",
88 | "Age": 28,
89 | "Country": "Canada"
90 | }
91 | ]
92 | ```
--------------------------------------------------------------------------------
/029_text_samples/005_template_with_data_formatting/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Template with Date Formatting
2 |
3 | This repository demonstrates how to use Go's `text/template` package to format data, specifically focusing on formatting `time.Time` values in templates. It showcases how to format dates in a human-readable way using Go's date formatting patterns.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers formatting time and date fields in Go templates.
9 | - It demonstrates how to use Go's date formatting string, specifically the format string `"Monday, January 2, 2006"`, to render dates in a readable format.
10 | - Using this technique, you can control the presentation of time data within templates.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "os"
21 | "text/template"
22 | "time"
23 | )
24 |
25 | type Event struct {
26 | Name string
27 | Date time.Time
28 | }
29 |
30 | func main() {
31 |
32 | // This template formats a time.Time field in a specific way using Go's date formatting.
33 | // The format string "Monday, January 2, 2006" is a standard Go way of specifying date formats
34 |
35 | tpl := `Event: {{.Name}}
36 | Date: {{.Date.Format "Monday, January 2, 2006"}}`
37 |
38 | t := template.Must(template.New("event").Parse(tpl))
39 |
40 | event := Event{
41 | Name: "Go Conference",
42 | Date: time.Now(),
43 | }
44 |
45 | err := t.Execute(os.Stdout, event)
46 | if err != nil {
47 | fmt.Println("Error executing template:", err)
48 | }
49 | }
50 | ```
51 |
52 | ### 🏃 How to Run
53 |
54 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
55 | 2. Clone this repository:
56 |
57 | ```bash
58 | git clone https://github.com/Rapter1990/go_sample_examples.git
59 | ```
60 |
61 | 3. Navigate to the `029_text_samples/005_template_with_data_formatting` directory:
62 |
63 | ```bash
64 | cd go_sample_examples/029_text_samples/005_template_with_data_formatting
65 | ```
66 |
67 | 4. Run the Go program:
68 |
69 | ```bash
70 | go run 005_template_with_data_formatting.go
71 | ```
72 |
73 | ### 📦 Output
74 |
75 | When you run the program, you should see the following output (the date will vary depending on the current time):
76 |
77 | ```
78 | Event: Go Conference
79 | Date: Wednesday, September 18, 2024
80 | ```
--------------------------------------------------------------------------------
/021_tickers/01_basic_ticker/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Basic Ticker
2 |
3 | This repository demonstrates the usage of tickers in Go, which are used to trigger actions at regular intervals. The example showcases how to create a simple ticker that ticks every second and stops after a specified duration.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers basic ticker usage in Go.
9 | - It demonstrates how to create a ticker, run it for a set amount of time, and stop it after a certain number of ticks.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "time"
20 | )
21 |
22 | func main() {
23 |
24 | // Tickers are used to perform an action at regular intervals for a specified duration.
25 | // A ticker can be created using the NewTicker function from the time package
26 |
27 | // Simple Ticker
28 | // create a ticker that ticks every 1 second
29 |
30 | // Create a ticker that ticks every 1 second
31 | ticker := time.NewTicker(1 * time.Second)
32 |
33 | // Stop the ticker after 5 ticks
34 | go func() {
35 | time.Sleep(5 * time.Second)
36 | ticker.Stop()
37 | }()
38 |
39 | // Print the tick events
40 | for t := range ticker.C {
41 | fmt.Println("Tick at", t)
42 | }
43 |
44 | fmt.Println("Ticker stopped.")
45 | }
46 | ```
47 |
48 | ### 🏃 How to Run
49 |
50 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
51 | 2. Clone this repository:
52 |
53 | ```bash
54 | git clone https://github.com/Rapter1990/go_sample_examples.git
55 | ```
56 |
57 | 3. Navigate to the `021_tickers/01_basic_ticker` directory:
58 |
59 | ```bash
60 | cd go_sample_examples/021_tickers/01_basic_ticker
61 | ```
62 |
63 | 4. Run the Go program:
64 |
65 | ```bash
66 | go run main.go
67 | ```
68 |
69 | ### 📦 Output
70 |
71 | When you run the program, you should see the following output, where the ticker prints a message every second and stops after 5 seconds:
72 |
73 | ```bash
74 | Tick at 2024-09-14 11:36:20.9222214 +0300 +03 m=+1.000559901
75 | Tick at 2024-09-14 11:36:21.9222214 +0300 +03 m=+2.000559901
76 | Tick at 2024-09-14 11:36:22.9222214 +0300 +03 m=+3.000559901
77 | Tick at 2024-09-14 11:36:23.9222214 +0300 +03 m=+4.000559901
78 | Tick at 2024-09-14 11:36:24.9222214 +0300 +03 m=+5.000559901
79 | fatal error: all goroutines are asleep - deadlock!
80 | ```
--------------------------------------------------------------------------------
/030_json/010_streaming_json_encoding/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Streaming JSON Encoding
2 |
3 | This repository demonstrates how to use streaming JSON encoding in Go to write JSON data directly to an output stream. It showcases encoding a slice of structs into JSON format and optionally formatting the output with indentation for readability.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example shows how to use the `json.Encoder` type to stream JSON encoding directly to an output stream, such as standard output.
9 | - It demonstrates how to set indentation for better readability and encode each struct in a slice individually.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "encoding/json"
19 | "fmt"
20 | "os"
21 | )
22 |
23 | type Person10 struct {
24 | Name string
25 | Age int
26 | Country string
27 | }
28 |
29 | func main() {
30 |
31 | people := []Person10{
32 | {"John", 30, "USA"},
33 | {"Alice", 28, "Canada"},
34 | {"Bob", 25, "UK"},
35 | }
36 |
37 | // Create a new JSON encoder that writes to standard output
38 | encoder := json.NewEncoder(os.Stdout)
39 |
40 | // Optionally set the encoder to use indentation for better readability
41 | encoder.SetIndent("", " ")
42 |
43 | // Encode each person individually
44 | for _, person := range people {
45 | err := encoder.Encode(person)
46 | if err != nil {
47 | fmt.Println("Error encoding JSON:", err)
48 | return
49 | }
50 | }
51 |
52 | }
53 | ```
54 |
55 | ### 🏃 How to Run
56 |
57 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
58 | 2. Clone this repository:
59 |
60 | ```bash
61 | git clone https://github.com/Rapter1990/go_sample_examples.git
62 | ```
63 |
64 | 3. Navigate to the `010_streaming_json_encoding` directory:
65 |
66 | ```bash
67 | cd go_sample_examples/030_json/010_streaming_json_encoding
68 | ```
69 |
70 | 4. Run the Go program:
71 |
72 | ```bash
73 | go run 010_streaming_json_encoding.go
74 | ```
75 |
76 | ### 📦 Output
77 |
78 | When you run the program, you should see the following output:
79 |
80 | ```json
81 | {
82 | "Name": "John",
83 | "Age": 30,
84 | "Country": "USA"
85 | }
86 | {
87 | "Name": "Alice",
88 | "Age": 28,
89 | "Country": "Canada"
90 | }
91 | {
92 | "Name": "Bob",
93 | "Age": 25,
94 | "Country": "UK"
95 | }
96 | ```
--------------------------------------------------------------------------------
/029_text_samples/004_nested_templates/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Nested Templates
2 |
3 | This repository demonstrates how to define and use nested templates in Go's `text/template` package. It showcases how to break down complex templates into smaller, reusable components.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the usage of nested templates in Go to improve readability and reuse of template code.
9 | - It demonstrates how to define a nested template for a person's address and include it within a larger template that renders a person's details.
10 | - Nested templates can be useful for separating logic and managing complex data structures within templates.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "os"
21 | "text/template"
22 | )
23 |
24 | type Address struct {
25 | City string
26 | Country string
27 | }
28 |
29 | type Person4 struct {
30 | Name string
31 | Age int
32 | Address Address
33 | }
34 |
35 | func main() {
36 |
37 | // This example shows how to define and use nested templates within a larger template.
38 | // The address template is defined and then included using the template keyword
39 |
40 | tpl := `{{define "address"}}{{.City}}, {{.Country}}{{end}}
41 |
42 | Name: {{.Name}}
43 | Age: {{.Age}}
44 | Address: {{template "address" .Address}}`
45 |
46 | t := template.Must(template.New("person").Parse(tpl))
47 |
48 | person := Person4{
49 | Name: "Dave",
50 | Age: 40,
51 | Address: Address{
52 | City: "Berlin",
53 | Country: "Germany",
54 | },
55 | }
56 |
57 | err := t.Execute(os.Stdout, person)
58 | if err != nil {
59 | fmt.Println("Error executing template:", err)
60 | }
61 | }
62 | ```
63 |
64 | ### 🏃 How to Run
65 |
66 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
67 | 2. Clone this repository:
68 |
69 | ```bash
70 | git clone https://github.com/Rapter1990/go_sample_examples.git
71 | ```
72 |
73 | 3. Navigate to the `029_text_samples/004_nested_templates` directory:
74 |
75 | ```bash
76 | cd go_sample_examples/029_text_samples/004_nested_templates
77 | ```
78 |
79 | 4. Run the Go program:
80 |
81 | ```bash
82 | go run 004_nested_templates.go
83 | ```
84 |
85 | ### 📦 Output
86 |
87 | When you run the program, you should see the following output:
88 |
89 | ```
90 | Name: Dave
91 | Age: 40
92 | Address: Berlin, Germany
93 | ```
--------------------------------------------------------------------------------
/029_text_samples/003_template_functions/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Template Functions
2 |
3 | This repository demonstrates how to use custom template functions in Go's `text/template` package. It shows how to register and use functions within templates to transform and manipulate data dynamically.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the usage of `FuncMap` in Go templates to register and apply custom functions like `strings.ToUpper` and `strings.ToLower`.
9 | - It demonstrates how to pass data into a template and modify it using built-in functions.
10 | - Focuses on rendering customized template outputs based on the input data and registered functions.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "os"
21 | "strings"
22 | "text/template"
23 | )
24 |
25 | type Person2 struct {
26 | Name string
27 | Age int
28 | Country string
29 | }
30 |
31 | func main() {
32 |
33 | // This example demonstrates how to use custom template functions.
34 | // The FuncMap is used to register functions like strings.ToUpper and strings.ToLower, which are then used in the template.
35 |
36 | funcMap := template.FuncMap{
37 | "ToUpper": strings.ToUpper,
38 | "ToLower": strings.ToLower,
39 | }
40 |
41 | tpl := `Name (upper): {{.Name | ToUpper}}
42 | Name (lower): {{.Name | ToLower}}
43 | Country: {{.Country}}`
44 |
45 | t := template.Must(template.New("person").Funcs(funcMap).Parse(tpl))
46 |
47 | person := Person2{
48 | Name: "Charlie",
49 | Age: 28,
50 | Country: "UK",
51 | }
52 |
53 | err := t.Execute(os.Stdout, person)
54 | if err != nil {
55 | fmt.Println("Error executing template:", err)
56 | }
57 | }
58 | ```
59 |
60 | ### 🏃 How to Run
61 |
62 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
63 | 2. Clone this repository:
64 |
65 | ```bash
66 | git clone https://github.com/Rapter1990/go_sample_examples.git
67 | ```
68 |
69 | 3. Navigate to the `029_text_samples/003_template_functions` directory:
70 |
71 | ```bash
72 | cd go_sample_examples/029_text_samples/003_template_functions
73 | ```
74 |
75 | 4. Run the Go program:
76 |
77 | ```bash
78 | go run 003_template_functions.go
79 | ```
80 |
81 | ### 📦 Output
82 |
83 | When you run the program, you should see the following output:
84 |
85 | ```
86 | Name (upper): CHARLIE
87 | Name (lower): charlie
88 | Country: UK
89 | ```
--------------------------------------------------------------------------------
/024_rate_limiter/004_rate_limiter_with_context/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Rate Limiter with `context.Context`
2 |
3 | This repository demonstrates how to implement rate limiting in Go using `context.Context`. It shows how to use context for request cancellation and control over processing times.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers implementing rate limiting using `context.Context` in Go.
9 | - It includes techniques for request cancellation and managing processing delays.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "context"
19 | "fmt"
20 | "time"
21 | )
22 |
23 | func processRequest(ctx context.Context, req int) {
24 | select {
25 | case <-ctx.Done():
26 | fmt.Println("Request", req, "cancelled at", time.Now())
27 | case <-time.After(200 * time.Millisecond):
28 | fmt.Println("Request", req, "processed at", time.Now())
29 | }
30 | }
31 |
32 | func main() {
33 |
34 | // Rate Limiting with context.Context
35 | // Use context.Context to implement rate limiting, which allows for more control over request cancellation
36 |
37 | requests := make(chan int, 5)
38 |
39 | for i := 1; i <= 5; i++ {
40 | requests <- i
41 | }
42 | close(requests)
43 |
44 | for req := range requests {
45 | ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
46 | processRequest(ctx, req)
47 | cancel()
48 | }
49 |
50 | }
51 | ```
52 |
53 | ### 🏃 How to Run
54 |
55 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
56 | 2. Clone this repository:
57 |
58 | ```bash
59 | git clone https://github.com/Rapter1990/go_sample_examples.git
60 | ```
61 |
62 | 3. Navigate to the 024_rate_limiter/004_rate_limiter_with_context directory:
63 |
64 | ```bash
65 | cd go_sample_examples/024_rate_limiter/004_rate_limiter_with_context
66 | ```
67 |
68 | 4. Run the Go program:
69 |
70 | ```bash
71 | go run main.go
72 | ```
73 |
74 | ### 📦 Output
75 |
76 | When you run the program, you should see output similar to:
77 |
78 | ```
79 | Request 1 processed at 2024-09-15 18:03:29.1501573 +0300 +03 m=+0.200704201
80 | Request 2 processed at 2024-09-15 18:03:29.3787454 +0300 +03 m=+0.429292301
81 | Request 3 processed at 2024-09-15 18:03:29.5790582 +0300 +03 m=+0.629605101
82 | Request 4 processed at 2024-09-15 18:03:29.7799347 +0300 +03 m=+0.830481601
83 | Request 5 processed at 2024-09-15 18:03:29.9803233 +0300 +03 m=+1.030870201
84 | ```
--------------------------------------------------------------------------------
/027_panic_and_defer/008_defer_log_functions_exit/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Defer Log Functions Exit
2 |
3 | This repository demonstrates the use of `defer` in Go to log function exits. The `defer` keyword ensures that a function call is executed after the surrounding function completes, even if it exits unexpectedly due to a panic. This example showcases how `defer` can be used to log the exit of each function.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the usage of `defer` to log function exits in Go.
9 | - The `defer` statement ensures that even when a panic occurs, the `exitLog` function is executed to log the function exit.
10 | - The example demonstrates how `defer` works in normal execution and in the presence of panics.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | )
21 |
22 | func main() {
23 | defer exitLog("main")
24 | fmt.Println("Main function running")
25 | performTask()
26 | }
27 |
28 | func performTask() {
29 | defer exitLog("performTask")
30 | fmt.Println("Task performed")
31 | panic("Panic in performTask")
32 | }
33 |
34 | func exitLog(funcName string) {
35 | fmt.Printf("Exiting %s\n", funcName)
36 | }
37 | ```
38 |
39 | ### 🏃 How to Run
40 |
41 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
42 | 2. Clone this repository:
43 |
44 | ```bash
45 | git clone https://github.com/Rapter1990/go_sample_examples.git
46 | ```
47 |
48 | 3. Navigate to the `027_panic_and_defer/008_defer_log_functions_exit` directory:
49 |
50 | ```bash
51 | cd go_sample_examples/027_panic_and_defer/008_defer_log_functions_exit
52 | ```
53 |
54 | 4. Run the Go program:
55 |
56 | ```bash
57 | go run 008_defer_log_functions_exit.go
58 | ```
59 |
60 | ### 📦 Output
61 |
62 | When you run the program, you should see the following output:
63 |
64 | ```bash
65 | Main function running
66 | Task performed
67 | Exiting performTask
68 | Exiting main
69 | panic: Panic in performTask
70 |
71 | goroutine 1 [running]:
72 | main.performTask()
73 | /path/to/your-repository/IdeaProjects/go_sample_examples/027_panic_and_defer/008_d
74 | efer_log_functions_exit/008_defer_log_functions_exit.go:16 +0x78
75 | main.main()
76 | /path/to/your-repository/go_sample_examples/027_panic_and_defer/008_d
77 | efer_log_functions_exit/008_defer_log_functions_exit.go:10 +0x6a
78 |
79 | Process finished with the exit code 2
80 |
81 | ```
--------------------------------------------------------------------------------
/026_sorting/005_sorting_a_custom_type_using_sort_interface/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Sorting a Custom Type Using sort.Interface
2 |
3 | This repository demonstrates how to sort a custom type in Go using the `sort.Interface`. It provides an example of defining a custom type `Person2` and implementing the `sort.Interface` methods (`Len`, `Swap`, and `Less`) to sort by a specific field, in this case, `Age`.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers sorting a custom type by implementing the `sort.Interface` in Go.
9 | - The custom type `Person2` is defined with `Name` and `Age` fields, and the sort order is determined by the `Age` field.
10 | - This is useful for sorting custom types in Go based on one or more fields.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```golang
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sort"
21 | )
22 |
23 | // Define the Person2 struct with Name and Age fields
24 | type Person2 struct {
25 | Name string
26 | Age int
27 | }
28 |
29 | // Define ByAge type, which is a slice of Person2
30 | type ByAge []Person2
31 |
32 | // Implementing the sort.Interface for ByAge
33 | func (a ByAge) Len() int { return len(a) }
34 | func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
35 | func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
36 |
37 | func main() {
38 |
39 | // Slice of Person2 structs to sort
40 | people := []Person2{
41 | {"Alice", 25},
42 | {"Bob", 30},
43 | {"Charlie", 20},
44 | }
45 |
46 | // Sorting the slice by age using the sort.Interface
47 | sort.Sort(ByAge(people))
48 |
49 | // Printing the sorted slice
50 | fmt.Println("Sorted by age using sort.Interface:", people)
51 | }
52 | ```
53 |
54 | ### 🏃 How to Run
55 |
56 | 1. Ensure you have Go installed. If not, download it from [here](https://golang.org/dl/).
57 | 2. Clone this repository:
58 |
59 | ```bash
60 | git clone https://github.com/Rapter1990/go_sample_examples.git
61 | ```
62 |
63 | 3. Navigate to the `005_sorting_a_custom_type_using_sort_interface` directory:
64 |
65 | ```bash
66 | cd go_sample_examples/026_sorting/005_sorting_a_custom_type_using_sort_interface
67 | ```
68 |
69 | 4. Run the Go program:
70 |
71 | ```bash
72 | go run main.go
73 | ```
74 |
75 | ### 📦 Output
76 |
77 | When you run the program, the output will display the sorted slice of `Person2` structs by age:
78 |
79 | ```bash
80 | Sorted by age using sort.Interface: [{Charlie 20} {Alice 25} {Bob 30}]
81 | ```
--------------------------------------------------------------------------------
/029_text_samples/001_conditional_logic_in_templates/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Conditional Logic in Templates
2 |
3 | This repository demonstrates the use of conditional logic in Go's `text/template` package. It shows how to handle conditions within templates to control the flow of content based on dynamic data, such as struct fields.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers basic conditional logic in Go templates.
9 | - It includes a demonstration of an `if` block to check the presence of a field and display alternate content if the condition is not met.
10 | - Shows how to render templates dynamically with struct data.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "os"
21 | "text/template"
22 | )
23 |
24 | type Person struct {
25 | Name string
26 | Age int
27 | Country string
28 | }
29 |
30 | func main() {
31 |
32 | // This template includes a conditional if block to check whether the Age field is present.
33 | // If it's not, an alternate message is shown
34 |
35 | person := Person{
36 | Name: "Alice",
37 | Age: 25,
38 | Country: "Canada",
39 | }
40 |
41 | tpl := `{{if .Age}}My name is {{.Name}} and I am {{.Age}} years old.{{else}}My name is {{.Name}} and I prefer not to disclose my age.{{end}}
42 | I live in {{.Country}}.`
43 |
44 | t := template.Must(template.New("person").Parse(tpl))
45 |
46 | err := t.Execute(os.Stdout, person)
47 | if err != nil {
48 | fmt.Println("Error executing template:", err)
49 | }
50 | }
51 | ```
52 |
53 | ### 🏃 How to Run
54 |
55 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
56 | 2. Clone this repository:
57 |
58 | ```bash
59 | git clone https://github.com/Rapter1990/go_sample_examples.git
60 | ```
61 |
62 | 3. Navigate to the `029_text_samples/001_conditional_logic_in_templates` directory:
63 |
64 | ```bash
65 | cd go_sample_examples/029_text_samples/001_conditional_logic_in_templates
66 | ```
67 |
68 | 4. Run the Go program:
69 |
70 | ```bash
71 | go run 001_conditional_logic_in_templates.go
72 | ```
73 |
74 | ### 📦 Output
75 |
76 | When you run the program, you should see the following output:
77 |
78 | ```
79 | My name is Alice and I am 25 years old.
80 | I live in Canada.
81 | ```
82 |
83 | If the `Age` field were missing or set to `0`, the template would display:
84 |
85 | ```
86 | My name is Alice and I prefer not to disclose my age.
87 | I live in Canada.
88 | ```
--------------------------------------------------------------------------------
/030_json/003_handling_nested_json_structures/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Handling Nested JSON Structures
2 |
3 | This repository demonstrates how to handle nested JSON objects in Go using structs within structs. It shows how to unmarshal nested JSON data into Go structures and perform operations on the decoded data.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers how to decode JSON objects with nested structures using Go structs and the `json.Unmarshal` function.
9 | - It demonstrates how to define structs that contain other structs, unmarshal JSON into these structs, and handle errors during the decoding process.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "encoding/json"
19 | "fmt"
20 | )
21 |
22 | type Address struct {
23 | City string
24 | State string
25 | Country string
26 | }
27 |
28 | type Person3 struct {
29 | Name string
30 | Age int
31 | Address Address
32 | }
33 |
34 | func main() {
35 |
36 | // This example illustrates how to handle nested JSON objects by defining structs within structs.
37 |
38 | jsonString := `{"Name":"Alice","Age":28,"Address":{"City":"Los Angeles","State":"CA","Country":"USA"}}`
39 |
40 | var person Person3
41 |
42 | err := json.Unmarshal([]byte(jsonString), &person)
43 | if err != nil {
44 | fmt.Println("Error decoding JSON:", err)
45 | return
46 | }
47 |
48 | // Marshal the struct back to JSON format
49 | jsonOutput, err := json.MarshalIndent(person, "", " ")
50 | if err != nil {
51 | fmt.Println("Error encoding JSON:", err)
52 | return
53 | }
54 |
55 | fmt.Println(string(jsonOutput))
56 |
57 | }
58 | ```
59 |
60 | ### 🏃 How to Run
61 |
62 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
63 | 2. Clone this repository:
64 |
65 | ```bash
66 | git clone https://github.com/Rapter1990/go_sample_examples.git
67 | ```
68 |
69 | 3. Navigate to the `003_handling_nested_json_structures` directory:
70 |
71 | ```bash
72 | cd go_sample_examples/030_json/003_handling_nested_json_structures
73 | ```
74 |
75 | 4. Run the Go program:
76 |
77 | ```bash
78 | go run 003_handling_nested_json_structures.go
79 | ```
80 |
81 | ### 📦 Output
82 |
83 | When you run the program, you should see the following output:
84 |
85 | ```json
86 | {
87 | "Name": "Alice",
88 | "Age": 28,
89 | "Address": {
90 | "City": "Los Angeles",
91 | "State": "CA",
92 | "Country": "USA"
93 | }
94 | }
95 | ```
--------------------------------------------------------------------------------
/028_string_manipulations/001_string_manipulations.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 | )
7 |
8 | var p = fmt.Println
9 |
10 | func main() {
11 |
12 | // String Manipulation
13 |
14 | // Contains
15 | p("Contains 'world' in 'Hello, world!': ", strings.Contains("Hello, world!", "world"))
16 |
17 | // Count
18 | p("Count occurrences of 'l' in 'Hello, world!': ", strings.Count("Hello, world!", "l"))
19 |
20 | // HasPrefix
21 | p("HasPrefix 'Hello' in 'Hello, world!': ", strings.HasPrefix("Hello, world!", "Hello"))
22 |
23 | // HasSuffix
24 | p("HasSuffix '!' in 'Hello, world!': ", strings.HasSuffix("Hello, world!", "!"))
25 |
26 | // Index
27 | p("Index of 'o' in 'Hello, world!': ", strings.Index("Hello, world!", "o"))
28 | p("Index of 'z' in 'Hello, world!': ", strings.Index("Hello, world!", "z"))
29 |
30 | // Join
31 | p("Join ['Hello', 'world'] with ', ': ", strings.Join([]string{"Hello", "world"}, ", "))
32 |
33 | // Repeat
34 | p("Repeat 'Go' 3 times: ", strings.Repeat("Go", 3))
35 |
36 | // Replace
37 | p("Replace 'l' with 'L' in 'Hello, world!' (-1 for all): ", strings.Replace("Hello, world!", "l", "L", -1))
38 | p("Replace 'l' with 'L' in 'Hello, world!' (first occurrence): ", strings.Replace("Hello, world!", "l", "L", 1))
39 |
40 | // ReplaceAll
41 | p("ReplaceAll 'foo' with 'bar' in 'foofoofoo': ", strings.ReplaceAll("foofoofoo", "foo", "bar"))
42 |
43 | // Split
44 | p("Split 'a-b-c-d-e' by '-': ", strings.Split("a-b-c-d-e", "-"))
45 | p("Split 'a,b,c,d,e' by ',': ", strings.Split("a,b,c,d,e", ","))
46 |
47 | // ToLower
48 | p("ToLower 'HELLO, WORLD!': ", strings.ToLower("HELLO, WORLD!"))
49 |
50 | // ToUpper
51 | p("ToUpper 'hello, world!': ", strings.ToUpper("hello, world!"))
52 |
53 | // Trim
54 | p("Trim spaces from ' Hello, world! ': ", strings.Trim(" Hello, world! ", " "))
55 |
56 | // TrimPrefix
57 | p("TrimPrefix 'Hello' from 'Hello, world!': ", strings.TrimPrefix("Hello, world!", "Hello"))
58 |
59 | // TrimSuffix
60 | p("TrimSuffix '!' from 'Hello, world!': ", strings.TrimSuffix("Hello, world!", "!"))
61 |
62 | // Fields (splits on whitespace)
63 | p("Fields in 'Hello world from Go!': ", strings.Fields("Hello world from Go!"))
64 |
65 | // Title
66 | p("Title case 'go is awesome': ", strings.Title("go is awesome"))
67 |
68 | // Map (custom mapping function)
69 | p("Map function to replace 'i' with 'I' in 'this is a test': ",
70 | strings.Map(func(r rune) rune {
71 | if r == 'i' {
72 | return 'I'
73 | }
74 | return r
75 | }, "this is a test"))
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/021_tickers/04_reset_ticker/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Resetting a Ticker
2 |
3 | This repository demonstrates how to reset a ticker in Go, allowing dynamic changes to the ticker's interval. Tickers trigger actions at regular intervals, and resetting a ticker adjusts the interval while keeping the ticker running.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers how to reset a ticker to dynamically change the interval during program execution.
9 | - It demonstrates starting a ticker, resetting the ticker's interval, and stopping the ticker after a specified time.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "time"
20 | )
21 |
22 | func main() {
23 |
24 | // Resetting a Ticker
25 | // Resetting a ticker allows you to change the ticker's interval dynamically
26 |
27 | // Create a ticker that ticks every 1 second
28 | ticker := time.NewTicker(1 * time.Second)
29 |
30 | go func() {
31 | for t := range ticker.C {
32 | fmt.Println("Tick at", t)
33 | }
34 | }()
35 |
36 | time.Sleep(3 * time.Second)
37 |
38 | // Reset the ticker to tick every 2 seconds instead of 1 second
39 | ticker.Reset(2 * time.Second)
40 |
41 | time.Sleep(6 * time.Second)
42 | ticker.Stop()
43 | fmt.Println("Ticker stopped.")
44 |
45 | // The ticker initially ticks every 1 second.
46 | // After 3 seconds, ticker.Reset(2 * time.Second) changes the interval to 2 seconds
47 | // The ticker continues ticking at the new interval until it is stopped
48 | }
49 | ```
50 |
51 | ### 🏃 How to Run
52 |
53 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
54 | 2. Clone this repository:
55 |
56 | ```bash
57 | git clone https://github.com/Rapter1990/go_sample_examples.git
58 | ```
59 |
60 | 3. Navigate to the `021_tickers/04_reset_ticker` directory:
61 |
62 | ```bash
63 | cd go_sample_examples/021_tickers/04_reset_ticker
64 | ```
65 |
66 | 4. Run the Go program:
67 |
68 | ```bash
69 | go run main.go
70 | ```
71 |
72 | ### 📦 Output
73 |
74 | When you run the program, you should see the following output:
75 |
76 | ```bash
77 | Tick at 2024-09-14 11:45:58.073901 +0300 +03 m=+1.000614901
78 | Tick at 2024-09-14 11:45:59.073901 +0300 +03 m=+2.000614901
79 | Tick at 2024-09-14 11:46:00.073901 +0300 +03 m=+3.000614901
80 | Tick at 2024-09-14 11:46:02.0745411 +0300 +03 m=+5.001255001
81 | Tick at 2024-09-14 11:46:04.0745411 +0300 +03 m=+7.001255001
82 | Tick at 2024-09-14 11:46:06.0745411 +0300 +03 m=+9.001255001
83 | Ticker stopped.
84 | ```
--------------------------------------------------------------------------------
/023_waitgroup/004_waitgroup_with_error_handling/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - WaitGroup with Error Handling
2 |
3 | This repository demonstrates how to use Go's `sync.WaitGroup` to synchronize goroutines and handle errors that may occur during their execution. The example showcases how to capture and process errors from multiple goroutines using a channel.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example demonstrates using a `sync.WaitGroup` with error handling in Go.
9 | - It includes a worker function that simulates tasks, where one worker intentionally encounters an error.
10 | - The example shows how to propagate errors back to the main goroutine using a channel and handle them appropriately after all workers finish execution.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sync"
21 | )
22 |
23 | func worker1(id int, wg *sync.WaitGroup, errors chan error) {
24 | defer wg.Done()
25 |
26 | // Simulate an error for worker 2
27 | if id == 2 {
28 | errors <- fmt.Errorf("worker %d encountered an error", id)
29 | return
30 | }
31 |
32 | fmt.Printf("Worker %d completed successfully\n", id)
33 | }
34 |
35 | func main() {
36 |
37 | // WaitGroup with Error Handling
38 | // we demonstrate using a WaitGroup with error handling in the workers
39 |
40 | var wg sync.WaitGroup
41 | errors := make(chan error, 3)
42 |
43 | for i := 1; i <= 3; i++ {
44 | wg.Add(1)
45 | go worker1(i, &wg, errors)
46 | }
47 |
48 | // Wait for all workers to finish
49 | wg.Wait()
50 | close(errors)
51 |
52 | // Check for errors
53 | for err := range errors {
54 | if err != nil {
55 | fmt.Println("Error:", err)
56 | }
57 | }
58 |
59 | fmt.Println("All workers completed.")
60 |
61 | }
62 | ```
63 |
64 | ### 🏃 How to Run
65 |
66 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
67 | 2. Clone this repository:
68 |
69 | ```bash
70 | git clone https://github.com/Rapter1990/go_sample_examples.git
71 | ```
72 |
73 | 3. Navigate to the `023_waitgroup` directory:
74 |
75 | ```bash
76 | cd go_sample_examples/023_waitgroup/004_waitgroup_with_error_handling
77 | ```
78 |
79 | 4. Run the Go program:
80 |
81 | ```bash
82 | go run 004_waitgroup_with_error_handling.go
83 | ```
84 |
85 | ### 📦 Output
86 |
87 | When you run the program, you should see the following output:
88 |
89 | ```bash
90 | Worker 3 completed successfully
91 | Worker 1 completed successfully
92 | Error: worker 2 encountered an error
93 | All workers completed.
94 | ```
--------------------------------------------------------------------------------
/025_atomic_counters/003_atomic_flag_using_sync_atomic/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Atomic Flag Using sync/atomic
2 |
3 | This repository demonstrates the use of an atomic flag in Go to control access to a critical section. It showcases how to use the `sync/atomic` package to implement an atomic boolean flag for concurrent programming.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the use of an atomic flag to manage access to a shared resource in concurrent goroutines.
9 | - It demonstrates how to use the `atomic.CompareAndSwapInt32` function to set and reset the flag, allowing only one goroutine to enter the critical section at a time.
10 | - Multiple goroutines attempt to access a critical section, but only one succeeds at a time by modifying the atomic flag.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sync"
21 | "sync/atomic"
22 | )
23 |
24 | func main() {
25 |
26 | // Atomic Flag Example Using sync/atomic
27 | // Demonstrate using an atomic boolean flag to control access to a critical section
28 |
29 | var flag int32 // Shared atomic flag
30 | var wg sync.WaitGroup
31 |
32 | for i := 0; i < 5; i++ {
33 | wg.Add(1)
34 | go func(id int) {
35 | defer wg.Done()
36 |
37 | if atomic.CompareAndSwapInt32(&flag, 0, 1) { // Try to set flag to 1
38 | fmt.Printf("Goroutine %d entered critical section\n", id)
39 | atomic.StoreInt32(&flag, 0) // Reset flag to 0
40 | } else {
41 | fmt.Printf("Goroutine %d did not enter critical section\n", id)
42 | }
43 | }(i)
44 | }
45 |
46 | wg.Wait()
47 | fmt.Println("All goroutines done.")
48 | }
49 | ```
50 |
51 | ### 🏃 How to Run
52 |
53 | 1. Ensure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
54 | 2. Clone this repository:
55 |
56 | ```bash
57 | git clone https://github.com/Rapter1990/go_sample_examples.git
58 | ```
59 |
60 | 3. Navigate to the **025_atomic_counters/003_atomic_flag_using_sync_atomic** directory:
61 |
62 | ```bash
63 | cd go_sample_examples/025_atomic_counters/003_atomic_flag_using_sync_atomic
64 | ```
65 |
66 | 4. Run the Go program:
67 |
68 | ```bash
69 | go run main.go
70 | ```
71 |
72 | ### 📦 Output
73 |
74 | When you run the program, you should see an output similar to:
75 |
76 | ```bash
77 | Goroutine 3 did not enter critical section
78 | Goroutine 0 entered critical section
79 | Goroutine 4 did not enter critical section
80 | Goroutine 2 did not enter critical section
81 | Goroutine 1 did not enter critical section
82 | All goroutines done.
83 | ```
--------------------------------------------------------------------------------
/029_text_samples/006_complex_structs_and_template_actions/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Complex Structs and Template Actions
2 |
3 | This repository demonstrates the use of complex structs and template actions in Go. It focuses on rendering nested struct data using Go's `text/template` package, showcasing how to display deeply nested fields using the `with` action for a cleaner and more focused template rendering.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the use of structs and nested structs in Go.
9 | - It showcases how to define templates that can render structured data with ease, including how to access nested fields in structs.
10 | - It uses Go’s template package to format and print data, focusing specifically on the `with` action to handle deeply nested fields efficiently.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "os"
21 | "text/template"
22 | )
23 |
24 | type Contact struct {
25 | Phone string
26 | Email string
27 | }
28 |
29 | type Person6 struct {
30 | Name string
31 | Age int
32 | Contact Contact
33 | }
34 |
35 | func main() {
36 |
37 | // The with action is used here to focus the template on a specific field (Contact) of the Person struct,
38 | // making it easier to work with deeply nested data
39 |
40 | tpl := `Name: {{.Name}}
41 | Age: {{.Age}}
42 | Contact Info:
43 | {{with .Contact}}
44 | Phone: {{.Phone}}
45 | Email: {{.Email}}
46 | {{end}}`
47 |
48 | t := template.Must(template.New("person").Parse(tpl))
49 |
50 | person := Person6{
51 | Name: "Eva",
52 | Age: 32,
53 | Contact: Contact{
54 | Phone: "123-456-7890",
55 | Email: "eva@example.com",
56 | },
57 | }
58 |
59 | err := t.Execute(os.Stdout, person)
60 | if err != nil {
61 | fmt.Println("Error executing template:", err)
62 | }
63 | }
64 | ```
65 |
66 | ### 🏃 How to Run
67 |
68 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
69 | 2. Clone this repository:
70 |
71 | ```bash
72 | git clone https://github.com/Rapter1990/go_sample_examples.git
73 | ```
74 |
75 | 3. Navigate to the `006_complex_structs_and_template_actions` directory:
76 |
77 | ```bash
78 | cd go_sample_examples/029_text_samples/006_complex_structs_and_template_actions
79 | ```
80 |
81 | 4. Run the Go program:
82 |
83 | ```bash
84 | go run 006_complex_structs_and_template_actions.go
85 | ```
86 |
87 | ### 📦 Output
88 |
89 | When you run the program, you should see the following output:
90 |
91 | ```
92 | Name: Eva
93 | Age: 32
94 | Contact Info:
95 | Phone: 123-456-7890
96 | Email: eva@example.com
97 | ```
--------------------------------------------------------------------------------
/019_range_over_channel/001_basic_example_range_over_channel/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Range Over Channel
2 |
3 | This repository demonstrates how to use the `range` keyword to iterate over values received from a channel in Go. It showcases a basic example where one Goroutine sends values to a channel, and the main Goroutine receives and processes those values using the `range` construct.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the basics of using channels and the `range` keyword to iterate over the values sent through a channel.
9 | - It includes the concept of channel creation, sending data into a channel using a Goroutine, and receiving data until the channel is closed.
10 | - The code illustrates the proper use of the `close()` function to signal that no more values will be sent to the channel.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | )
21 |
22 | func main() {
23 |
24 | // Basic Example: Range Over a Channel
25 | // A single Goroutine sends a series of integers to a channel,
26 | // and the main Goroutine iterates over these values using range.
27 |
28 | ch := make(chan int)
29 |
30 | // Start a Goroutine that sends values to the channel
31 | go func() {
32 | for i := 0; i < 5; i++ {
33 | ch <- i
34 | }
35 | close(ch) // Close the channel after sending all values
36 | }()
37 |
38 | // Use range to receive values from the channel until it's closed
39 | for value := range ch {
40 | fmt.Println("Received:", value)
41 | }
42 |
43 | fmt.Println("Channel closed, no more data.")
44 | }
45 | ```
46 |
47 | ### 🏃 How to Run
48 |
49 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
50 | 2. Clone this repository:
51 |
52 | ```bash
53 | git clone https://github.com/Rapter1990/go_sample_examples.git
54 | ```
55 |
56 | 3. Navigate to the `019_range_over_channel/001_basic_example_range_over_channel` directory:
57 |
58 | ```bash
59 | cd go_sample_examples/019_range_over_channel/001_basic_example_range_over_channel
60 | ```
61 |
62 | 4. Run the Go program:
63 |
64 | ```bash
65 | go run main.go
66 | ```
67 |
68 | ### 📦 Output
69 |
70 | When you run the program, you should see the following output:
71 |
72 | ```
73 | Received: 0
74 | Received: 1
75 | Received: 2
76 | Received: 3
77 | Received: 4
78 | Channel closed, no more data.
79 | ```
80 |
81 | This example demonstrates how Goroutines can be used to send data through channels and how the `range` keyword can be used to receive and process data until the channel is closed.
82 | ```
83 |
--------------------------------------------------------------------------------
/024_rate_limiter/002_rate_limiter_burst_capacity/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Rate Limiter with Burst Capacity
2 |
3 | This repository demonstrates a rate limiter implementation in Go that includes burst capacity. It shows how to allow a burst of requests before enforcing a rate limit.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers rate limiting techniques with burst capacity in Go.
9 | - It includes an implementation that allows a burst of requests before enforcing a rate limit using a buffered channel.
10 |
11 |
12 | ## 💻 Code Example
13 |
14 | ```go
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "time"
20 | )
21 |
22 | func main() {
23 |
24 | // Rate Limiting with a Burst Capacity
25 | // Demonstrate how to allow a burst of requests before enforcing the rate limit
26 |
27 | requests := make(chan int, 5)
28 |
29 | for i := 1; i <= 5; i++ {
30 | requests <- i
31 | }
32 | close(requests)
33 |
34 | // Create a buffered channel to allow a burst of up to 3 requests
35 | burstLimiter := make(chan time.Time, 3)
36 |
37 | // Initially fill the burstLimiter channel to allow immediate processing of up to 3 requests
38 | for i := 0; i < 3; i++ {
39 | burstLimiter <- time.Now()
40 | }
41 |
42 | // Fill the burstLimiter channel every 200 milliseconds to maintain the rate limit
43 | go func() {
44 | for t := range time.Tick(200 * time.Millisecond) {
45 | burstLimiter <- t
46 | }
47 | }()
48 |
49 | for req := range requests {
50 | <-burstLimiter // Wait for a token from burstLimiter
51 | fmt.Println("Request", req, "processed at", time.Now())
52 | }
53 |
54 | }
55 | ```
56 |
57 | ### 🏃 How to Run
58 |
59 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
60 | 2. Clone this repository:
61 |
62 | ```bash
63 | git clone https://github.com/Rapter1990/go_sample_examples.git
64 | ```
65 |
66 | 3. Navigate to the 024_rate_limiter/002_rate_limiter_burst_capacity directory:
67 |
68 | ```bash
69 | cd go_sample_examples/024_rate_limiter/002_rate_limiter_burst_capacity
70 | ```
71 |
72 | 4. Run the Go program:
73 |
74 | ```bash
75 | go run main.go
76 | ```
77 |
78 | ### 📦 Output
79 |
80 | When you run the program, you should see output similar to:
81 |
82 | ```
83 | Request 1 processed at 2024-09-15 17:53:36.3855689 +0300 +03 m=+0.000517001
84 | Request 2 processed at 2024-09-15 17:53:36.4178194 +0300 +03 m=+0.032767501
85 | Request 3 processed at 2024-09-15 17:53:36.4178194 +0300 +03 m=+0.032767501
86 | Request 4 processed at 2024-09-15 17:53:36.5866023 +0300 +03 m=+0.201550401
87 | Request 5 processed at 2024-09-15 17:53:36.7855888 +0300 +03 m=+0.400536901
88 | ```
--------------------------------------------------------------------------------
/027_panic_and_defer/007_chain_panic_and_defer/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Chain Panic and Defer
2 |
3 | This repository demonstrates the use of chained `panic` and `defer` in Go. It showcases how to recover from a panic, handle the recovery, and then re-trigger a new panic, allowing partial recovery from errors while still stopping execution as needed.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the chaining of `panic` and `recover` with `defer` in Go.
9 | - The `recover` function allows capturing the panic and taking necessary actions (e.g., logging or cleanup).
10 | - In this case, after recovering from the initial panic, a new panic is triggered, demonstrating how recovery can be used to handle errors before re-panicking.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | )
21 |
22 | func main() {
23 |
24 | // You can chain panic and recover to allow partial recovery and continue execution after a panic
25 |
26 | defer func() {
27 | if r := recover(); r != nil {
28 | fmt.Println("Recovered in main:", r)
29 | panic("panic again")
30 | }
31 | }()
32 | funcThatPanics()
33 | fmt.Println("This will not be printed")
34 | }
35 |
36 | func funcThatPanics() {
37 | panic("Original panic")
38 | }
39 | ```
40 |
41 | ### 🏃 How to Run
42 |
43 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
44 | 2. Clone this repository:
45 |
46 | ```bash
47 | git clone https://github.com/Rapter1990/go_sample_examples.git
48 | ```
49 |
50 | 3. Navigate to the `027_panic_and_defer/007_chain_panic_and_defer` directory:
51 |
52 | ```bash
53 | cd go_sample_examples/027_panic_and_defer/007_chain_panic_and_defer
54 | ```
55 |
56 | 4. Run the Go program:
57 |
58 | ```bash
59 | go run main.go
60 | ```
61 |
62 | ### 📦 Output
63 |
64 | When you run the program, you should see the following output:
65 |
66 | ```bash
67 | Recovered in main: Original panic
68 | panic: Original panic [recovered]
69 | panic: panic again
70 |
71 | goroutine 1 [running]:
72 | main.main.func1()
73 | /path/to/your-repository/go_sample_examples/027_panic_and_defer/007_c
74 | hain_panic_and_defer/007_chain_panic_and_defer.go:14 +0x78
75 | panic({0xc82180?, 0xcc0478?})
76 | /path/to/your-repository/Go/src/runtime/panic.go:785 +0x132
77 | main.funcThatPanics(...)
78 | /path/to/your-repository/go_sample_examples/027_panic_and_defer/007_c
79 | hain_panic_and_defer/007_chain_panic_and_defer.go:22
80 | main.main()
81 | /path/to/your-repository/go_sample_examples/027_panic_and_defer/007_c
82 | hain_panic_and_defer/007_chain_panic_and_defer.go:17 +0x3f
83 | ```
--------------------------------------------------------------------------------
/025_atomic_counters/002_ atomic_counter _with_decrement_and_compare_and_swap/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Atomic Counter with Decrement and Compare-And-Swap (CAS)
2 |
3 | This repository demonstrates how to use atomic operations in Go, including incrementing, decrementing, and using the Compare-And-Swap (CAS) function to manipulate shared variables safely in concurrent programs.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the use of atomic operations to perform safe updates on shared variables across multiple goroutines.
9 | - It showcases how to increment and decrement a counter using `atomic.AddInt32`, and how to use the `Compare-And-Swap` (CAS) function for conditional updates.
10 | - A `WaitGroup` is used to ensure that all goroutines complete before printing the final value of the counter.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sync"
21 | "sync/atomic"
22 | )
23 |
24 | func main() {
25 |
26 | // Atomic Counter with Decrement and Compare-And-Swap (CAS)
27 | // Use atomic operations to increment, decrement, and use the compare-and-swap operation
28 |
29 | var counter int32 = 100 // Initialize counter
30 | var wg sync.WaitGroup
31 |
32 | // Increment goroutine
33 | wg.Add(1)
34 | go func() {
35 | atomic.AddInt32(&counter, 1) // Increment counter
36 | wg.Done()
37 | }()
38 |
39 | // Decrement goroutine
40 | wg.Add(1)
41 | go func() {
42 | atomic.AddInt32(&counter, -1) // Decrement counter
43 | wg.Done()
44 | }()
45 |
46 | // Compare-And-Swap goroutine
47 | wg.Add(1)
48 | go func() {
49 | // CAS: If counter equals 100, set it to 200
50 | if atomic.CompareAndSwapInt32(&counter, 100, 200) {
51 | fmt.Println("CAS successful, new value:", counter)
52 | } else {
53 | fmt.Println("CAS failed, current value:", counter)
54 | }
55 | wg.Done()
56 | }()
57 |
58 | wg.Wait()
59 | fmt.Println("Final Counter:", counter)
60 | }
61 | ```
62 |
63 | ### 🏃 How to Run
64 |
65 | 1. Ensure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
66 | 2. Clone this repository:
67 |
68 | ```bash
69 | git clone https://github.com/Rapter1990/go_sample_examples.git
70 | ```
71 |
72 | 3. Navigate to the **025_atomic_counters/002_atomic_counter_with_decrement_and_compare_and_swap** directory:
73 |
74 | ```bash
75 | cd go_sample_examples/025_atomic_counters/002_atomic_counter_with_decrement_and_compare_and_swap
76 | ```
77 |
78 | 4. Run the Go program:
79 |
80 | ```bash
81 | go run main.go
82 | ```
83 |
84 | ### 📦 Output
85 |
86 | When you run the program, you should see an output similar to:
87 |
88 | ```bash
89 | CAS successful, new value: 200
90 | Final Counter: 200
91 | ```
--------------------------------------------------------------------------------
/025_atomic_counters/004_atomic_counter_with_load_and_store_operations/README.md:
--------------------------------------------------------------------------------
1 | # Go Sample Example - Atomic Counter with Load and Store Operations
2 |
3 | This repository demonstrates the use of atomic load and store operations in Go to safely read and update a counter in concurrent goroutines. It showcases how to use the `sync/atomic` package to ensure thread-safe manipulation of shared variables.
4 |
5 | ## 📖 Information
6 |
7 |
8 | - This example covers the use of atomic load and store operations to safely read and update a shared counter variable in concurrent goroutines.
9 | - It demonstrates the use of `atomic.LoadInt64` for reading the current value of a counter and `atomic.StoreInt64` for updating it.
10 | - Multiple goroutines increment the counter, while one goroutine uses load and store operations to read and update the counter concurrently.
11 |
12 |
13 | ## 💻 Code Example
14 |
15 | ```go
16 | package main
17 |
18 | import (
19 | "fmt"
20 | "sync"
21 | "sync/atomic"
22 | )
23 |
24 | func main() {
25 |
26 | // Atomic Counter with Load and Store Operations
27 | // Illustrate using atomic load and store operations to ensure safe reading and updating of a counter
28 |
29 | var counter int64 // Shared atomic counter
30 | var wg sync.WaitGroup
31 |
32 | // Increment counter in goroutines
33 | for i := 0; i < 5; i++ {
34 | wg.Add(1)
35 | go func() {
36 | for j := 0; j < 1000; j++ {
37 | atomic.AddInt64(&counter, 1)
38 | }
39 | wg.Done()
40 | }()
41 | }
42 |
43 | // Load and store operations
44 | wg.Add(1)
45 | go func() {
46 | defer wg.Done()
47 | current := atomic.LoadInt64(&counter) // Atomically load the counter value
48 | fmt.Println("Current Counter:", current)
49 | atomic.StoreInt64(&counter, current+1000) // Atomically set counter to current + 1000
50 | fmt.Println("Updated Counter:", atomic.LoadInt64(&counter))
51 | }()
52 |
53 | wg.Wait()
54 | fmt.Println("Final Counter:", counter)
55 |
56 | }
57 | ```
58 |
59 | ### 🏃 How to Run
60 |
61 | 1. Make sure you have Go installed. If not, you can download it from [here](https://golang.org/dl/).
62 | 2. Clone this repository:
63 |
64 | ```bash
65 | git clone https://github.com/Rapter1990/go_sample_examples.git
66 | ```
67 |
68 | 3. Navigate to the **025_atomic_counters/004_atomic_counter_with_load_and_store_operations** directory:
69 |
70 | ```bash
71 | cd go_sample_examples/025_atomic_counters/004_atomic_counter_with_load_and_store_operations
72 | ```
73 |
74 | 4. Run the Go program:
75 |
76 | ```bash
77 | go run main.go
78 | ```
79 |
80 | ### 📦 Output
81 |
82 | When you run the program, you should see an output similar to:
83 |
84 | ```bash
85 | Current Counter: 0
86 | Updated Counter: 1000
87 | Final Counter: 1000
88 | ```
89 |
--------------------------------------------------------------------------------