Memo of Golang Part 1
Based on Go v1.15
In the recent practice of Golang, there’re many trivial knowledges that worthy to be memorized in daily coding. So I came up with the idea to have this series basicly for my own memorization. if it helps anyone else, it would be great.
Comments and error messages convention
The convention has been defined in Effective Go, but there’re something that might be hard to notice.
-
A comment for packages or functions, etc should be ended with a period. Using such punctuations increases the readablity of comments.
//Repeat returns a string that repeats given string N times.
-
An error message shouldn’t have the initial letter upper case unless there’s certain acronym and use any ending punctuation.
errors.New("oops, there're something wrong")
Since usually an error message will be logged with other context like:
log.Printf("An error happened when reading %s like %v", filename, err)
So the upper case initial letter “O” would look strange in middle of outputs like “An error happened when reading 1.txt like Oops, there’re something wrong”.
strings.Builder
“+=” VS “strings.Builder”
- “+=”
The naive concat of strings “+=” simply have to copy two strings into a newly allocated memory. So if there’re many strings with constant lengths, the time complexity of it will be O(N2). So if there’s no many strings to be concat, we may use naive concat, but avoid using it when there’re too many strings. - strings.Builder
- strings.Builder uses an internal slice. When write into the builder, the builder will append bytes to the inner slice. So the time complexity of this is O(N)
- It’s more efficient to pre-define the capacity of the slice inside the builder, if we can predict the capacity usage by using the function “Grow”.
strings.Repeat
The function is useful when need to repeat certain string N times.
strconv.Itoa
strconv.Itoa is for convert int to string. like 97 to “97”.
Sprintf is also can be used for this, but not as efficient as Itoa.
And strconv.FormatInt is more flexible for this.
Iteration over map
For loop can be used for iteration over a map. But be careful when the order of the key-value pairs matters. Then we can use slice instead, or sort the keys and iterate.
Split by regexp
strings.Split only supports string separators, we can use Split method inside regexp to split by regexp.
Swap values of two variables
Simply by i, j = j, i
Self defined types for long and complex types
For some type like func(x, y int) int, better define a type for it like:
type foldFunc func(x, y int) int
math.Hypot for calculating hypotenuse
math.Hypot(x, y)
iota can be used in const definations for increasing numbers
const (
//A = 0
A = iota
//B = 1
B = iota
_ = iota
//C = 3
C = iota
)
The above can be simplified into:
const (
//A = 0
A = iota
//B = 1
B
_
//C = 3
C
)
and the result would be the same.
And we can also use a common expression with iota:
const (
//A = 0
A = iota * 2
//B = 2 (1 * 2)
B
_
//C = 6 (3 * 2)
C
)
unicode package
Package unicode has lots of useful functions to deal with type rune. Including lots of Is… and some To…
utf8 package
Package utf8 provides functions like get the first or last rune from a []byte or string like:
str := "Hello, 世界"
for len(str) > 0 {
r, size := utf8.DecodeLastRuneInString(str)
fmt.Printf("%c %v\n", r, size)
str = str[:len(str)-size]
}
And we also can simply use range to iterate runes in string:
for i, r := range runeString {}