Life goes on, go on!!!
Today, I want to share some useful, simple golang code snippets with you.
Change the value of string
First of all, we need to know that in golang, string is immutable:
str := "hello"
str[0] = 'c'
Compilation error: cannot assign to str[0]
Correct practice:
package main
import (
"fmt"
)
func main() {
str := "hello"
c := []byte(str)
c[0] = 'f'
str2 := string(c)
fmt.Println(str2)
}
Output: fello
Get a substring
In golang, there is no substring-like function, but how do we get substrings?
The answer is slice, slice:
package main
import "fmt"
func main() {
value := "cat;dog"
// Take substring from index 4 to length of string.
substring := value[4:len(value)]
fmt.Println(substring)
}
Output: dog
Traversal string output
People who switch from other languages to golang may not be used to for range. Let's look at using for range to output every character in a string:
package main
import "fmt"
func main() {
value := "cat;dog"
for ch := range value {
fmt.Println(ch)
}
}
Output:
1
2
3
4
5
6
You may find that the index is output, not every character.
package main
import "fmt"
func main() {
value := "cat;dog"
for _, ch := range value {
fmt.Println(ch)
}
}
Output:
99
97
116
59
100
111
103
But that's not what you want, so:
package main
import "fmt"
func main() {
value := "cat;dog"
for _, ch := range value {
fmt.Println(string(ch))
}
}
bytes and characters in strings
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
value := "Love"
i := utf8.RuneCountInString(value)
fmt.Println(i)
j := len(value)
fmt.Println(j)
}
Output:
2
6
Query a value in a two-dimensional array or slice
package main
import (
"fmt"
)
func main() {
v := 11
arr2Dim := [2][2]int{}
arr2Dim[0][0] = 1
arr2Dim[0][1] = 11
arr2Dim[1][0] = 111
arr2Dim[1][1] = 1111
found := false
Found:
for row := range arr2Dim {
for column := range arr2Dim[row] {
if arr2Dim[row][column] == v {
found = true
break Found
}
}
}
fmt.Println(found)
}
Output:true
Check if there is a key in the map
package main
import (
"fmt"
)
func main() {
map1 := map[string]int{"one": 1, "two": 2}
val1, isPresent := map1["one"]
fmt.Println(val1)
fmt.Println(isPresent)
val2, isPresent2 := map1["three"]
fmt.Println(val2)
fmt.Println(isPresent2)
}
Output:
1
true
0
false
Detecting whether a value implements an interface
package main
import (
. "launchpad.net/gocheck"
"testing"
)
func Test(t *testing.T) {
TestingT(t)
}
type MySuite struct{}
var _ = Suite(&MySuite{})
type IFoobar interface {
foobar()
}
type Foobar struct {
}
func (f *Foobar) foobar() {
}
func (s *MySuite) TestFoobar(c *C) {
v := Foobar{}
var i interface{} = v
_, ok := i.(IFoobar)
c.Assert(ok, Equals, false)
var p interface{} = &v
_, ok = p.(IFoobar)
c.Assert(ok, Equals, true)
}
Open and read files
Using os.Open
package main
import (
"io"
"os"
)
func main() {
// open input file
fi, err := os.Open("input.txt")
if err != nil {
panic(err)
}
// close fi on exit and check for its returned error
defer func() {
if err := fi.Close(); err != nil {
panic(err)
}
}()
// open output file
fo, err := os.Create("output.txt")
if err != nil {
panic(err)
}
// close fo on exit and check for its returned error
defer func() {
if err := fo.Close(); err != nil {
panic(err)
}
}()
// make a buffer to keep chunks that are read
buf := make([]byte, 1024)
for {
// read a chunk
n, err := fi.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if n == 0 {
break
}
// write a chunk
if _, err := fo.Write(buf[:n]); err != nil {
panic(err)
}
}
}
Use outil.ReadFile
package main
import (
"io/ioutil"
)
func main() {
// read the whole file at once
b, err := ioutil.ReadFile("input.txt")
if err != nil {
panic(err)
}
// write the whole body at once
err = ioutil.WriteFile("output.txt", b, 0644)
if err != nil {
panic(err)
}
}
Check whether a channel is closed
if input, open := <-ch; !open {
break
}