Golang in short
🔔 Prelude: No need for digging a big hole, just use it. Golang in short Go is A modern high-level programming language that resembles C Open-source, compiled, statically typed, and memory-safe Go has Simple yet powerful package management (pulls directly from GitHub) Built-in concurrency primitives Garbage collection (GC) Lightning-fast compilation Minimal syntax Cross-platform compilation Go doesn’t have Classes and inheritance Function overloading Implicit type conversions I use Go to Say goodbye to Java’s verbose syntax Build web services and microservices Handle high-concurrency scenarios Go is perfect for Web services and RESTful APIs Microservices architecture Network programming and distributed systems Go might not be ideal for GUI desktop applications Kernel development Machine learning (Python has a stronger ecosystem) Installing Go Using OS package managers Linux: apt, yum, snap macOS: brew Windows: choco, scoop, etc. Download official precompiled binaries Already compiled, ready to use Set up path and links manually Verify with go version Hello World // This is a comment /* This is a multiline comment */ package main // This is the main package // No semicolons at line endings import ( "fmt" "math" ) // Importing other packages const myConstant int = 0 // Constants need explicit initialization func main() { fmt.Println("helloworld") // Package names -> lowercase // Lowercase in package -> myConstant -> package-private // Capitalized -> Println() -> exported (public) } Types bool string int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr // Has pointers but no pointer arithmetic byte // alias for uint8 rune // alias for int32 // Represents a Unicode code point // From ancient Nordic "rune" float32 float64 complex64 complex128 // Zero value for reference types is nil // Type assertion t, ok := variable.(int) // Returns two values, ok indicates success // Panics if ok is not captured and type is wrong // Type conversion var myInt int32 = 42 myAnotherInt := int64(myInt) // Type conversion // No direct conversion between bool and int // Generally, single characters and numbers can convert // Otherwise, only conversions within same type family Variables and Functions var hi bool = true // Variables outside functions must have explicit types func myFunc(x, y int) (int, int) { innerHi := "hi" // Inside functions, use := for type inference const hiConst = "hi again" // Constants cannot use := return x + 1, y + 1 } func MapFilter[T any, R comparable]( slice []T, mapper func(T) R, predicate func(R) bool, ) func(options ...int) (filtered []R, count int, err error) { // Returns a function return func(options ...int) (filtered []R, count int, err error) { // Implementation return } } // A complete function signature example // Note the second func starts parameters // The last func starts return type -> returns a function // T is generic, R is constraint, but they're essentially the same thing func(x int) int { return x * 2 } // Anonymous function definition Arrays, Slices, and Maps // Arrays - fixed length var arr [5]int = [5]int{1, 2, 3, 4, 5} arr2 := [...]int{1, 2, 3} // Compiler infers length // Slices - dynamic length var slice []int = []int{1, 2, 3} slice2 := make([]int, 5) // Length 5 slice3 := make([]int, 5, 10) // Length 5, capacity 10 // Maps var m map[string]int = map[string]int{"one": 1, "two": 2} m2 := make(map[string]int) m2["key"] = 42 // Check if key exists value, exists := m["key"] if exists { fmt.Println(value) } Control Flow // Only for loops exist // All parts of for loop are optional for i := 0; i < 10; i++ { // Loop body } // Infinite loop for { // Equivalent to while(true) } // Condition loop i := 0 for i < 10 { i++ } for i, v := range expression {} // Iterate over iterables // Similar to Python's for..in // Directly provides index and value // No enumerate function needed // Use _, v to ignore index // if statement if v := 5; v < 6 { // Can assign in condition // Condition body } // switch statement switch x := 5; x { // x is optional case 1: fmt.Println("one") case 2, 3, 4: // Multiple values fmt.Println("two, three or four") default: fmt.Println("other") } // Type switch switch v := x.(type) { case int: fmt.Printf("int: %d\n", v) case string: fmt.Printf("string: %s\n", v) default: fmt.Printf("unknown type\n") } Defer and Channels // defer - deferred execution (stack structure, LIFO) defer fmt.Println(1) defer fmt.Println(2) defer fmt.Println(3) panic("!") // Output order: 3 2 1 panic // defer provides stack-based deferred execution // panic triggers deferred functions // channel - channels (queue structure, FIFO) func channelExample() { myChan := make(chan int, 2) // Buffer size 2 myChan <- 10 // 10 goes in myChan <- 20 // then 20 goes in took := <-myChan // took is 10 fmt.Println(<-myChan) // 20 } func blockingChannel() { ch := make(chan int) // Unbuffered channel // ch <- 1 // Will block! Need another goroutine to receive // Correct approach go func() { ch <- 1 }() fmt.Println(<-ch) } // Channels provide a queue-like or pipe-like structure // FIFO Pointers // Go has pointers // Useful when referencing large data // Go's design philosophy is very close to C-family languages // Fun fact: When passing pointers to functions, both C and Go copy the pointer // All parameters are pass-by-value in both languages // But C++ has completely different reference passing mechanism func main() { var myPtr *int // var anotherPtr uintptr // uintptr is integer type, not pointer i := 42 myPtr = &i // Take address fmt.Println(*myPtr) // Dereference, outputs 42 *myPtr = 43 // Modify through pointer fmt.Println(i) // Outputs 43 // No pointer arithmetic } Format Verbs Verb Description Example Output %v (value) Default format Printf("%v", people) {zhangsan} %+v Adds field names for structs Printf("%+v", people) {Name:zhangsan} %#v Go syntax representation Printf("%#v", people) main.Human{Name:“zhangsan”} %T (type) Type in Go syntax Printf("%T", people) main.Human %% Percent sign Printf("%%") % %t (true) true or false Printf("%t", true) true %b (binary) Binary representation Printf("%b", 5) 101 %c (char) Unicode character Printf("%c", 0x4E2D) 中 %d (decimal) Decimal Printf("%d", 0x12) 18 %o (octal) Octal Printf("%o", 10) 12 %q (quote) Single-quoted character literal Printf("%q", 0x4E2D) ‘中’ %x Hexadecimal, lowercase Printf("%x", 13) d %X Hexadecimal, uppercase Printf("%X", 13) D %U (unicode) Unicode format: U+1234 Printf("%U", 0x4E2D) U+4E2D %b Binary exponent scientific notation Printf("%b", 10.5) 5835037194198p-49 %e Scientific notation Printf("%e", 10.2) 1.020000e+01 %E Scientific notation Printf("%E", 10.2) 1.020000E+01 %f (float) Decimal point, no exponent Printf("%f", 10.2) 10.200000 %g Compact format (%e or %f) Printf("%g", 10.20) 10.2 %G Compact format (%E or %f) Printf("%G", 10.20) 10.2 %s (string) String (string or []byte) Printf("%s", []byte(“Go”)) Go %q Double-quoted string Printf("%q", “Go”) “Go” %x Hex, lowercase, two chars per byte Printf("%x", “golang”) 676f6c616e67 %X Hex, uppercase, two chars per byte Printf("%X", “golang”) 676F6C616E67 %p (pointer) Hexadecimal with 0x prefix Printf("%p", &people) 0x4f57f0 + Always print sign; ASCII-only for %+q Printf("%+q", “中文”) “\u4e2d\u6587” - Pad with spaces on right (left-align) # Alternate format: 0 prefix for octal (%#o), 0x for hex (%#x), etc. Printf("%#U", ‘中’) U+4E2D ‘中’ ’ ' Space for elided sign; spaces between bytes for hex 0 Pad with zeros; moves padding after sign for numbers Reference: ...