├── 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | --------------------------------------------------------------------------------