Myths of Golang
--
from rubyist perspective
Everything in go pass by value
Go variable without defining
- if it is integer it will be zero by default
- if it is boolean it will be false by default
- if it is string it will be empty string
Naked return
- Normal return
func Hello() (string) {
hello := "hello"
return hello
}
- Naked return
func Hello() (hello string) {
hello = "hello"
return
}
Variable with Initializer
We can omit the type if declaring variable with initializer var i, j = 1, 2
Short Variable Declaration
s := ”foo”
is not available outside function
Multiple Variables
var a, b, c string
can be declared with factored block
Type Conversion
Need to be in this expression T(v), otherwise it will raise error
Constant
Cannot be declared with short declaration :=
Conditional Statements
- for loop and if statement has no parentheses
- for loop init and post expression is option, so it will become while loop technically
- Variable can be declared in if statement, like ruby but its scope is within if statement
- Switch without condition is like switch true
defer
is executed after all surrounding functions are execute. Multiple defer is like the stack
Pointer
- pointer instantiate:
var p *int
- pointer passing to a function
func foo(p *int){...}
- print address:
fmt.Println(p)
- print value:
fmt.Println(*p)
package mainimport (
"fmt"
)func main() {
x := 1
var p *int
p = &x
fmt.Println("value:", x)
fmt.Println("address:", &x)
fmt.Println("address:", p)
foo(&x)
}
func foo(x *int){
fmt.Println("print value inside function:", *x)
fmt.Println("print address inside function:", x)}value: 1
address: 0xc000094010
address: 0xc000094010
print value inside function: 1
print address inside function: 0xc000094010
Pointer to Struct
To access field of struct via pointer, we don’t have to have *
Slice
- When slice is passed to a function, it is passed as copy of the slice. any modification in the function does not affect original slide.
- To modify of the slice in the function, it need to pass slice pointer instead
- nil slice is not empty slice. Empty slice can grow, but nil slice cannot grow
- string is a readonly slice of bytes. This way of design, it is very efficient to have substring from a string. They both safely point to same array
Array and Slice
- Array has fix size, but slice has dynamic size
- Slice is the reference to underlying array. If changes the slice value, the underlying value will change too
- Slice or array value can be struct too
- Slice length and capacity are different. Slice length is slice length. Slice capacity is underlying array length
CAP rule
Slice can be sliced these rule:
- slice from lower bound, capacity will be decrease
- slice from upper bound, capacity will be the same
- with append function, cap is not reliable. It depends on new allocated underlying array length. It could never be equal to length of slice
Range
- Range form iteration over slice or map
- for with range, the first element is index of slice. The second element is value of slice
Map
- Map declare with var is not usable. it is a nil map. The usable map is declared with
make
Function value
Function can be a value too. It can pass to another function as parameter
Closure
- Function can return a closure. Closure is a function value (function) that references variable outside its body
Method
- Method is a special function with receiver as a type (struct)
Pointer receiver
use pointer receiver when:
- You want to modify receiver in the method
- More efficient not to copy value on each method call in the case large struct
Function and Pointer
- Function with pointer argument must take pointer otherwise will return error.
- Function with value argument must take value otherwise will return error.
Method and Receiver
Method with pointer or value receiver can take both value or pointer as receiver when they are called.
Interface
- Interface is a set of method signatures. Each method can have multiple receivers
- Interface value and type: when calling method, go handles null pointer exception gracefully when it has interface type but no value. However it will be run time error if it has no value and type when calling method.
Type assertion
Check if interface hold value of specific type
Go Concurrency
- Goroutines: functions that is executed concurrently. function to execute independently from main thread. Be aware of: if main thread is stopped. The routines are stopped too.
- Channels: what to be shared/accessed between routines
- Channel Direction: the restriction of channel to send/receive value. By default channel has bi-direction. for example:
restrict to only send value (write only):c chan<- int
restrict to only receive value (read only):c <-chan int
can both send/receive:c chan int
- Select: switch case for channel
- Buffered Channels: the channel capacity, max number of values that can be sent to channel
String vs []byte
- string is immutable — more memory storing
- []byte is mutable — more efficient, in-place modifying
ioutil.ReadAll
avoid using it reading request body. It may cause a memory leak with a large request body. Instead, use a decoder that filters out data and it is more efficient and concise.
Rune type
— todo