Several Ways to Stop Goroutine in Go.
A signal channel
Typically, you pass the goroutine a (possibly separate) signal channel. That signal channel is used to push a value into when you want the goroutine to stop. The goroutine polls that channel regularly. As soon as it detects a signal, it quits.
package main
import (
"fmt"
"time"
)
func main() {
done := make(chan bool)
go func() {
for {
select {
case <-done:
fmt.Println("done")
return
default:
// ...
}
}
}()
fmt.Println("A")
time.Sleep(time.Millisecond)
done <- true
}
$ go run main.go
A
done
Using close Function
To close a channel, we call the built-in close function:
package main
import (
"fmt"
)
func main() {
c1 := make(chan int)
go func() {
for {
v, ok := <-c1
if !ok {
fmt.Println("done")
return
}
fmt.Println(v)
}
}()
c1 <- 1
c1 <- 2
close(c1)
// panic: send on closed channel
c1 <- 3
}
$ go run main.go
1
2
done
panic: send on closed channel
Use the context
Package context defines the Context type, which carries deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes.
package main
import (
"context"
"fmt"
)
func main() {
c1 := make(chan int)
ctx, cancel := context.WithCancel(context.Background())
go func(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("done")
return
default:
fmt.Println(<-c1)
}
}
}(ctx)
c1 <- 1
c1 <- 2
cancel()
// fatal error:
c1 <- 3
}
$ go run main.go
1
2
done
fatal error: all goroutines are asleep - deadlock!
Catching return values from goroutines in Go.
Channels
A channel is a communication mechanism that lets one goroutine send values to another goroutine.
Make a main.go file containing the following:
package main
import (
"fmt"
"time"
)
func main() {
c1 := make(chan int)
c2 := make(chan string)
go func() {
time.Sleep(2 * time.Second)
c1 <- 10
}()
go func() {
time.Sleep(time.Second)
c2 <- "One"
}()
// Fetch
for i := 0; i < 2; i++ {
// Await both of these values
// simultaneously, printing each one as it arrives.
select {
case m1 := <-c1:
fmt.Println("received ", m1)
case m2 := <-c2:
fmt.Println("received ", m2)
}
}
}
$ go run main.go
received One
received 10
Defer, Panic, and Recover in Go.
panic
During a typical panic, normal execution stops, all deferred function calls in that goroutine are executed, and the program crashes with a log message.
package main
func main() {
panic("invalid")
}
$ go run main.go
panic: invalid
goroutine 1 [running]:
main.main()
/data/main.go:5 +0x27
exit status 2
When a panic occurs, all deferred functions are run in reverse order, starting with those of the topmost function on the stack and proceeding up to main, as the program below demonstrates:
package main
import "fmt"
func main() {
f(2)
}
func f(x int) {
fmt.Printf("f(%d)\n", x+0/x) // panics if x == 0
defer fmt.Printf("defer %d\n", x)
f(x - 1)
}
$ go run main.go
f(2)
f(1)
defer 1
defer 2
panic: runtime error: integer divide by zero
goroutine 1 [running]:
main.f(0x4b4268?)
/data/main.go:12 +0x114
main.f(0x1)
/data/main.go:14 +0xf6
main.f(0x2)
/data/main.go:14 +0xf6
main.main()
/data/main.go:7 +0x1e
exit status 2
Recover
Let's see an example:
package main
import "fmt"
func main() {
f(2)
}
func f(x int) {
defer func() {
if p := recover(); p != nil {
fmt.Printf("internal error: %v\n", p)
}
}()
fmt.Printf("f(%d)\n", x+0/x) // panics if x == 0
f(x - 1)
}
$ go run main.go
f(2)
f(1)
internal error: runtime error: integer divide by zero
Understanding defer in Go.
Deferred Function Calls
A defer statement is an ordinary function or method call prefixed by the keyword defer. The function and argument expressions are evaluated when the statement is executed, but the actual call is deferred until the function that contains the defer statement has finished, whether normally, by executing a return statement or falling off the end, or abnormally, by panicking. Any number of calls may be deferred;they are executed in the reverse of the order in which they were deferred.
package main
import "fmt"
func main() {
defer fmt.Println("World") // deferred until main() exits
// Multiple defer statements
defer fmt.Println("B")
defer fmt.Println("A")
fmt.Println("Hello")
}
$ go run main.go
Hello
A
B
World
Examples
A defer statement is often used with paired operations like open and close, connect and dis- connect, or lock and unlock to ensure that resources are released in all cases, no matter how complex the control flow. The right place for a defer statement that releases a resource is immediately after the resource has been successfully acquired.
package main
import (
"log"
"net/http"
)
func main() {
resp, err := http.Get("https://installmd.com/")
if err != nil {
log.Println(err)
}
defer resp.Body.Close()
}
$ go run main.go
Risky
Because deferred functions aren’t executed until the very end of a function’s execution, a defer statement in a loop deserves extra scrutiny. The code below could run out of file descriptors since no file will be closed until all files have been processed:
for _, filename := range filenames {
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close() // NOTE: risky; could run out of file descriptors
// ...process f...
}
One solution is to move the loop body, including the defer statement, into another function that is called on each iteration.
for _, filename := range filenames {
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close() // NOTE: risky; could run out of file descriptors
// ...process f...
}
Variadic Functions Tutorial with Examples in Go.
Variadic Function
A variadic function is one that can be called with varying numbers of arguments. The most familiar examples are fmt.Printf and its variants.
package main
import "fmt"
func add(vals ...int) int {
total := 0
for _, val := range vals {
total += val
}
return total
}
func main() {
fmt.Println(add())
fmt.Println(add(2))
fmt.Println(add(4, 5, 6))
values := []int{1, 2, 3, 4}
fmt.Println(add(values...)) // "10"
}
$ go run main.go
0
2
15
10
Examples
Join concatenates the elements of its first argument to create a single string.
package main
import "fmt"
func join(sep string, elems ...string) string {
var s string
for i, v := range elems {
if i == 0 {
s = v
} else {
s += sep + v
}
}
return s
}
func main() {
s := join(",", "A", "B", "C")
fmt.Println(s)
fmt.Println(join(",", "A"))
fmt.Println(join(","))
}
$ go run main.go
A,B,C
A
Benchmark
After running the benchmark, we receive the following results:
func BenchmarkJoin(b *testing.B) {
s := []string{"A", "B", "C"}
for i := 0; i < b.N; i++ {
join(",", s...) // 86.54 ns/op
// strings.Join(s, ",") 46.82 ns/op
}
}
$ go test -bench=. --count=1
join 86.54 ns/op
Join 46.82 ns/op
Closures and Anonymous Functions in Go.
Anonymous Function
A function literal is written like a function declaration, but without a name following the func keyword. It is an expression, and its value is called an anonymous function.
package main
import "fmt"
// squares returns a function that returns
// the next square number each time it is called.
func squares() func() int {
var x int
return func() int {
x++
return x * x
}
}
func main() {
f := squares()
fmt.Println(f()) // "1"
fmt.Println(f()) // "4"
fmt.Println(f()) // "9"
fmt.Println(f()) // "16"
}
$ go run main.go
1
4
9
16
Examples
Passing arguments to anonymous functions.
package main
import "fmt"
// Assigning function to the variable
var (
area = func(i1, i2 int) int {
return i1 * i2
}
)
func main() {
func(i1, i2 int) {
fmt.Println(i1 + i2)
}(4, 5)
fmt.Println(area(3, 4))
}
$ go run main.go
9
12
Testing the equivalence of maps in Go.
reflect.DeepEqual Function
It first checks if both maps are nil, then it checks if they have the same length before finally checking to see if they have the same set of (key, value) pairs.
package main
import (
"fmt"
"reflect"
)
func main() {
m1 := map[string]int{
"a": 1,
"b": 2,
}
m2 := map[string]int{
"b": 2,
"a": 1,
}
m3 := map[string]int{
"b": 3,
"c": 2,
}
fmt.Println(reflect.DeepEqual(m1, m2)) // true
fmt.Println(reflect.DeepEqual(m1, m3)) // false
}
$ go run main.go
true
false
Comparison
To test whether two maps contain the same keys and the same associated values, we must write a loop:
package main
import (
"fmt"
)
func main() {
m1 := map[string]int{
"a": 1,
"b": 2,
}
m2 := map[string]int{
"b": 2,
"a": 1,
}
m3 := map[string]int{
"b": 3,
"c": 2,
}
fmt.Println(EqualMap(m1, m2)) // true
fmt.Println(EqualMap(m1, m3)) // false
}
func EqualMap(x, y map[string]int) bool {
if len(x) != len(y) {
return false
}
for k, xv := range x {
if yv, ok := y[k]; !ok || yv != xv {
return false
}
}
return true
}
$ go run main.go
true
false
Benchmark
After running the benchmark, we receive the following results:
func BenchmarkEqualMap(b *testing.B) {
for i := 0; i < b.N; i++ {
EqualMap(m1, m3) // false
// reflect.DeepEqual(m1, m3)
}
}
$ go test -bench=. --count=1
EqualMap 47.59 ns/op
DeepEqual 493.80 ns/op
Working with Constants and iota in Go.
The Constant Generator iota
Here’s an example from the time package, which defines named constants of type Weekday for the days of the week, starting with zero for Sunday. Types of this kind are often called enu- merations, or enums for short.
package main
import "fmt"
type Weekday int
const (
Sunday Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
func main() {
fmt.Println("Sunday", Sunday)
fmt.Println("Monday", Monday)
fmt.Println("Saturday", Saturday)
}
$ go run main.go
Sunday 0
Monday 1
Saturday 6
The value of iota is still incremented for every entry in a constant list even if iota is not used:
package main
import "fmt"
const (
C0 = iota + 1 // Start from one
C1 = iota
C2 = iota
_
C4 = iota // Skip value
)
func main() {
fmt.Println(C0, C1, C2, C4) // "1 1 2 4"
}
$ go run main.go
1 1 2 4
Iota example
As a more complex example of iota, this declaration names the powers of 1024:
package main
import "fmt"
const (
_ = 1 << (10 * iota)
KiB // 1024
MiB // 1048576
GiB // 1073741824
TiB // 1099511627776 (exceeds 1 << 32)
PiB // 1125899906842624
EiB // 1152921504606846976
ZiB // 1180591620717411303424 (exceeds 1 << 64)
YiB // 1208925819614629174706176
)
func main() {
fmt.Printf("KiB: %d\n", KiB)
fmt.Printf("PiB: %d\n", PiB)
}
$ go run main.go
KiB: 1024
PiB: 1125899906842624
Golang bytes.Buffer Examples
Examples of Golang bytes.Buffer
The bytes package provides the Buffer type for efficient manipulation of byte slices. A Buffer starts out empty but grows as data of types like string, byte, and []byte are written to it.
Make a main.go file containing the following:
package main
import (
"bytes"
"fmt"
)
func main() {
// New Buffer.
var b bytes.Buffer
// Write strings to the Buffer.
b.WriteString("bytes")
b.WriteString(".")
b.WriteString("Buffer")
// Convert to a string and print it.
fmt.Println(b.String())
}
$ go run main.go
bytes.Buffer
As the example below shows, a bytes.Buffer variable requires no initialization because its zero value is usable:
package main
import (
"bytes"
"fmt"
)
// IntsToStr is like fmt.Sprintf(values) but adds commas.
func IntsToStr(values []int) string {
var buf bytes.Buffer
buf.WriteByte('[')
for i, v := range values {
if i > 0 {
buf.WriteString(", ")
}
fmt.Fprintf(&buf, "%d", v)
}
buf.WriteByte(']')
return buf.String()
}
func main() {
fmt.Println(IntsToStr([]int{4, 5, 6, 7}))
fmt.Println(IntsToStr([]int{}))
}
$ go run main.go
[4, 5, 6, 7]
[]
Reusing bytes.Buffer
You can use code like this:
package main
import (
"bytes"
"fmt"
)
var buf bytes.Buffer
func reuseValue(n int, s string) []byte {
buf.Reset()
for i := 0; i < n; i++ {
buf.WriteString(s)
}
return buf.Bytes()
}
func main() {
fmt.Println(string(reuseValue(4, "a")))
fmt.Println(string(reuseValue(4, "ab")))
fmt.Println(string(reuseValue(4, "cc")))
}
$ go run main.go
aaaa
abababab
cccccccc
Formatting float to currency string in Go.
Using localized formatting
Use golang.org/x/text/message to print using localized formatting for any language in the Unicode CLDR.
Make a main.go file containing the following:
package main
import (
"golang.org/x/text/language"
"golang.org/x/text/message"
)
func main() {
p := message.NewPrinter(language.English)
p.Printf("%v\n", 1000)
p.Printf("%v\n", 1000.02)
}
$ go run main.go
1,000
1,000.02
A classic example of recursion
The argument to comma is a string. If its length is less than or equal to 3, no comma is neces- sary. Otherwise, comma calls itself recursively with a substring consisting of all but the last three characters, and appends a comma and the last three characters to the result of the recur- sive call.
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(comma("-100"))
fmt.Println(comma("1000"))
fmt.Println(comma("1000.02"))
fmt.Println(comma(".020"))
}
// comma inserts commas in a non-negative decimal integer string.
func comma(s string) string {
neg := ""
if s[0:1] == "-" {
neg = "-"
s = s[1:]
}
end := strings.Index(s, ".")
point := ""
if end >= 0 {
point = s[end:]
s = s[0:end]
}
n := len(s)
if n <= 3 {
return neg + s + point
}
return neg + comma(s[:n-3]) + "," + s[n-3:] + point
}
$ go run main.go
-100
1,000
1,000.02
.020
Golang path and filepath Examples.
Using filepath.Base
The number is the index of the last slash in the string. If you want to get the file's base name, use filepath.Base:
package main
import (
"fmt"
"path/filepath"
)
func main() {
path := "a/b.c.go"
fmt.Println(filepath.Base(path)) // b.c.go
}
$ go run main.go
b.c.go
Using filepath.Split
Split splits path immediately following the final Separator, separating it into a directory and file name component.
package main
import (
"fmt"
"path/filepath"
)
func main() {
path := "a/b.c.go"
_, file := filepath.Split(path)
fmt.Println(file) // b.c.go
}
$ go run main.go
b.c.go
The basename Function
The basename function below was inspired by the Unix shell utility of the same name. In our version, basename(s) removes any prefix of s that looks like a file system path with com- ponents separated by slashes, and it removes any suffix that looks like a file type:
package main
import (
"fmt"
)
func main() {
fmt.Println(basename("a/b.c.go")) // b.c
fmt.Println(basename("a.c.go")) // a.c
fmt.Println(basename("abc")) // abc
}
// basename removes directory components and a .suffix.
// e.g., a => a, a.go => a, a/b/c.go => c, a/b.c.go => b.c
func basename(s string) string {
// Discard last '/' and everything before.
for i := len(s) - 1; i >= 0; i-- {
if s[i] == '/' {
s = s[i+1:]
break
}
}
// Preserve everything before last '.'.
for i := len(s) - 1; i >= 0; i-- {
if s[i] == '.' {
s = s[:i]
break
}
}
return s
}
$ go run main.go
b.c
a.c
abc
A simpler version uses the strings.LastIndex library function:
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(basename("a/b.c.go")) // b.c
fmt.Println(basename("a.c.go")) // a.c
fmt.Println(basename("abc")) // abc
}
func basename(s string) string {
slash := strings.LastIndex(s, "/") // -1 if "/" not found
s = s[slash+1:]
if dot := strings.LastIndex(s, "."); dot >= 0 {
s = s[:dot]
}
return s
}
$ go run main.go
b.c
a.c
abc
Calculate degrees celcius from farenheit in Go.
Following program shows you how to convert fahrenheit to celsius.
The function FToC below encapsu- lates the temperature conversion logic so that it is defined only once but may be used from multiple places. Here main calls it twice, using the values of two different local constants:
package main
import "fmt"
func main() {
const freezingF, boilingF = 32.0, 212.0
fmt.Printf("%g°F = %g°C\n", freezingF, FToC(freezingF)) // "32°F = 0°C"
fmt.Printf("%g°F = %g°C\n", boilingF, FToC(boilingF)) // "212°F = 100°C"
}
func FToC(f float64) float64 {
return (f - 32) * 5 / 9
}
$ go run main.go
32°F = 0°C
212°F = 100°C
Understanding Rune in Go.
UTF-8 Decoder
The unicode/utf8 package provides one that we can use like this:
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
s := "Hello, 世界"
for i := 0; i < len(s); {
r, size := utf8.DecodeRuneInString(s[i:])
fmt.Printf("%d\t%c\n", i, r)
i += size
}
}
$ go run main.go
0 H
1 e
2 l
3 l
4 o
5 ,
6
7 世
10 界
Go’s Range Loop
A range loop decodes a UTF-8-encoded string.
package main
import (
"fmt"
)
func main() {
s := "Hello, 世界"
for i, r := range s {
fmt.Printf("%d\t%q\t%d\n", i, r, r)
}
}
$ go run main.go
0 'H' 72
1 'e' 101
2 'l' 108
3 'l' 108
4 'o' 111
5 ',' 44
6 ' ' 32
7 '世' 19990
10 '界' 30028
We could use a simple range loop to count the number of runes in a string, like this:
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
s := "Hello, 世界"
n := 0
for range s {
n++
}
fmt.Println("Count ::", n)
// Or we can just call utf8.RuneCountInString(s).
fmt.Println("Count ::", utf8.RuneCountInString(s))
}
$ go run main.go
Count :: 9
Count :: 9
A []rune Conversion
A []rune conversion applied to a UTF-8-encoded string returns the sequence of Unicode code points that the string encodes:
package main
import (
"fmt"
)
func main() {
// "program" in Japanese katakana
s := "こんにちは"
fmt.Printf("% x\n", s) // "e3 81 93 e3 82 93 e3 81 ab e3 81 a1 e3 81 af"
r := []rune(s)
fmt.Printf("%x\n", r) // "[3053 3093 306b 3061 306f]"
fmt.Println(string(r))
fmt.Println(string(0x306f)) // "は"
}
$ go run main.go
e3 81 93 e3 82 93 e3 81 ab e3 81 a1 e3 81 af
[3053 3093 306b 3061 306f]
こんにちは
は
Introduction to Strings in Go. What is a String?
A string is an immutable sequence of bytes. Strings may contain arbitrary data, including bytes with value 0, but usually they contain human-readable text.
Make a main.go file containing the following:
package main
import "fmt"
func main() {
s := "Hello, 世界"
fmt.Println(len(s)) // "13"
fmt.Println(utf8.RuneCountInString(s)) // "9"
fmt.Println(s[0], s[7]) // "72 228" ('H', '\x8c')
// panic: index out of range
// c := s[len(s)]
fmt.Println(s[0:5]) // "Hello"
fmt.Println(s[:5]) // "Hello"
fmt.Println(s[7:]) // "世界"
fmt.Println(s[8:]) // "??界"
fmt.Println(s[:]) // "Hello, 世界"
// "世界"
// "\xe4\xb8\x96\xe7\x95\x8c"
// "\u4e16\u754c"
// "\U00004e16\U0000754c"
}
$ go run main.go
13
9
72 228
Hello
Hello
世界
??界
Hello, 世界
All escape characters
Within a double-quoted string literal, escape sequences that begin with a backslash \ can be used to insert arbitrary byte values into the string.
\a
‘‘alert’’ or bell
\b
backspace
\f
form feed
\n
newline
\r
carriage return
\t
tab
\v
vertical tab
\'
single quote (only in the rune literal '\'')
\"
double quote (only within "..." literals)
\\
backslash
Multiline strings
Simply use the backtick (`) character when declaring or assigning your string value.
package main
import "fmt"
func main() {
s := `This is a
multiline
string.`
fmt.Println(s)
}
$ go run main.go
This is a
multiline
string.
An example program using numbers.
Integers And Floating Point Numbers
Go has several different types to represent numbers. Generally we split numbers into two different kinds: integers and floating-point numbers.
Make a main.go file containing the following:
package main
import "fmt"
func main() {
fmt.Println("1 + 2 =", 1+2)
// a floating point number
fmt.Println("1 + 2 =", 1.0+2.0)
}
$ go run main.go
1 + 2 = 3
1 + 2 = 3
In addition to addition Go has several other operators:
package main
import "fmt"
func main() {
fmt.Println("5 + 3 =", 5+3)
// subtraction
fmt.Println("5 - 3 =", 5-3)
// multiplication
fmt.Println("5 * 3 =", 5*3)
// division
fmt.Println("5 / 3 =", 5/3)
// remainder
fmt.Println("5 % 3 =", 5%3)
}
$ go run main.go
5 + 3 = 8
5 - 3 = 2
5 * 3 = 15
5 / 3 = 1
5 % 3 = 2
Golang max int
To get the maximum value of the int64 type, use math.MaxInt64 constant.
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("int64 max:", math.MaxInt64)
// based on the platform you are executing
maxInt := int(^uint(0) >> 1)
fmt.Println("int max:", maxInt)
}
$ go run main.go
int64 max: 9223372036854775807
int max: 9223372036854775807
In Rust, there are 2 ways to sort a vector.
Using sort Method
The sort(&mut self) method sorts the slice. This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case. For example,
fn main() {
let mut v = [3, -5, 2, 6, 1];
v.sort();
println!("{:?}", v);
let mut s = ["b", "d", "c", "a"];
s.sort();
println!("{:?}", s);
}
[-5, 1, 2, 3, 6]
["a", "b", "c", "d"]
Using sort_by Method
The sort_by(&mut self, compare: F) method sorts the slice with a comparator function. The comparator function must define a total ordering for the elements in the slice. If the ordering is not total, the order of the elements is unspecified. For example,
fn main() {
let mut v = [5, 4, 1, 3, 2];
v.sort_by(|a, b| a.cmp(b));
println!("{:?}", v);
let mut s = ["b", "d", "c", "a"];
s.sort_by(|a, b| b.cmp(a));
println!("{:?}", s);
}
[1, 2, 3, 4, 5]
["d", "c", "b", "a"]
In Golang, there are 2 ways to check if a slice contains an element.
Using contains Function
The following example should cover whatever you are trying to do:
package main
import "fmt"
func Contains[E comparable](s []E, v E) bool {
for _, vs := range s {
if vs == v {
return true
}
}
return false
}
func main() {
s := []string{"Gopher", "Alice", "Bob"}
fmt.Println(Contains(s, "Bob"))
fmt.Println(Contains(s, "bob"))
}
true
false
Using slices.Contains Function
Starting with Go 1.18, you can use the slices package – specifically the generic Contains function:
package main
import (
"fmt"
"golang.org/x/exp/slices"
)
func main() {
s := []string{"Gopher", "Alice", "Bob"}
b := slices.Contains(s, "Bob")
fmt.Println(b)
b = slices.Contains(s, "bob")
fmt.Println(b)
}
true
false
In Golang, using the sort.Slice function is the easiest way to sort a slice
Using Slice Function
You simply pass an anonymous function to the sort.Slice function:
package main
import (
"fmt"
"sort"
)
func main() {
s := []string{"Houston", "Atlanta", "Boston"}
sort.Slice(s, func(i, j int) bool {
return s[i] < s[j]
})
fmt.Println(s)
a := []int{6, 4, 2}
sort.Slice(a, func(i, j int) bool {
return a[i] < a[j]
})
fmt.Println(a)
}
[Atlanta Boston Houston]
[2 4 6]
Slice sorts the slice x given the provided less function. It panics if x is not a slice.
See the following example:
package main
import (
"fmt"
"sort"
)
func main() {
people := []struct {
Name string
Age int
}{
{"Gopher", 7},
{"Alice", 55},
{"Vera", 24},
{"Bob", 75},
}
sort.Slice(people, func(i, j int) bool { return people[i].Name < people[j].Name })
fmt.Println("By name:", people)
sort.Slice(people, func(i, j int) bool { return people[i].Age < people[j].Age })
fmt.Println("By age:", people)
}
By name: [{Alice 55} {Bob 75} {Gopher 7} {Vera 24}]
By age: [{Gopher 7} {Vera 24} {Alice 55} {Bob 75}]
In Golang, there are 2 ways to check string is in json format.
Using Unmarshal Function
The following example should cover whatever you are trying to do:
package main
import (
"encoding/json"
"fmt"
)
func isJson(s string) bool {
var js json.RawMessage
return json.Unmarshal([]byte(s), &js) == nil
}
func isQuotedJson(s string) bool {
var js map[string]interface{}
return json.Unmarshal([]byte(s), &js) == nil
}
func main() {
s := `{"key":"value"}`
b := isJson(s)
fmt.Println(b)
b = isQuotedJson(s)
fmt.Println(b)
}
true
true
Using Standard Library Function
Standard encoding/json library contains json.Valid function starting from go 1.9. This function may be used for checking whether the provided string is a valid json:
package main
import (
"encoding/json"
"fmt"
)
func main() {
s := `{"key":"value"}`
b := json.Valid([]byte(s))
fmt.Println(b)
}
true
In Golang, there are 2 ways to duplicate slices.
Using append Function
You could write one simple statement to make a shallow copy of a slice.
The following example should cover whatever you are trying to do:
package main
import "fmt"
type T int
func main() {
a := []T{1, 2}
b := append([]T(nil), a...)
fmt.Println(a, b)
b[1] = 4
fmt.Println(a, b)
}
[1 2] [1 2]
[1 2] [1 4]
Using copy Function
See the following example:
package main
import "fmt"
type T int
func main() {
a := []T{1, 2}
b := make([]T, len(a))
copy(b, a)
fmt.Println(a, b)
b[1] = 4
fmt.Println(a, b)
}
[1 2] [1 2]
[1 2] [1 4]
In Python, using the __file__ is the easiest way to get name of current script.
Using Module Attributes
You can use __file__ to get the name of the current file. When used in the main module, this is the name of the script that was originally invoked.
See the following example:
#!/usr/bin/python3
# Import module
import os
print(__file__)
# omit the directory part
print(os.path.basename(__file__))
/home/python/demo.py
demo.py
In Python, there are 2 ways to determine whether a given integer is between two other integers.
Using Comparisons
Unlike C, all comparison operations in Python have the same priority, which is lower than that of any arithmetic, shifting or bitwise operation. Also unlike C, expressions like a
See the following example:
#!/usr/bin/python3
i = 20
if 10 < i < 40:
print(True)
True
Using range
For example,
#!/usr/bin/python3
i = 10
r = range(10, 30)
if i in range(10, 30):
print(True)
print(30 in r)
print(20 in r)
True
False
True
In Python, there are 2 ways to delete a character from a string.
Using replace Method
The str.replace(old, new[, count]) method returns a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced.
See the following example:
#!/usr/bin/python3
s = "Hello"
s = s.replace("l", "")
print(s)
Heo
Using Slice Syntax
Specify the start index and the end index, separated by a colon, to return a part of the string.
For example,
#!/usr/bin/python3
# remove character
def remove(str, rep):
i = str.find(rep)
if i == -1:
return str
str = str[:i]+str[i+1:]
return remove(str, rep)
s = "Hello"
s = remove(s, 'l')
print(s)
Heo
In Python, there are 2 ways to make a list of alphabet characters.
Using string Module
The string.ascii_lowercase is a pre-initialized string used as string constant. In Python, string ascii_lowercase will give the lowercase letters ‘abcdefghijklmnopqrstuvwxyz’.
See the following example:
#!/usr/bin/python3
# Import module
import string
# string.ascii_lowercase
# string.ascii_uppercase
# string.ascii_letters
ls = list(string.ascii_lowercase)
print(ls)
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
Using range Function
The range(start, stop[, step]) function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and stops before a specified number.
For example,
#!/usr/bin/python3
ls = list(map(chr, range(97, 123)))
print(ls)
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
String module features:
Object type:
##### string.whitespace
\t\n\r\v\f
##### string.ascii_letters
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
##### string.ascii_lowercase
abcdefghijklmnopqrstuvwxyz
##### string.ascii_uppercase
ABCDEFGHIJKLMNOPQRSTUVWXYZ
##### string.digits
0123456789
##### string.hexdigits
0123456789abcdefABCDEF
##### string.octdigits
01234567
##### string.printable
digits + ascii_letters + punctuation + whitespace
##### string.punctuation
!"#$%&\'()*+,-./:;?@[\\]^_`{|}~
In Golang, using the Unmarshal JSON function is the easiest way to Marshal / Unmarshal json with a custom type attribute.
JSON (JavaScript Object Notation) is a lightweight data-interchange format.
Using UnmarshalJSON Function
Example on custom UnmarshalJSON and MarshalJSON.
The following example should cover whatever you are trying to do:
package main
import (
"encoding/json"
"fmt"
"strconv"
"time"
)
type CustTimeUinx int64
func (t *CustTimeUinx) UnmarshalJSON(b []byte) error {
s, _ := strconv.Unquote(string(b))
uinx := int64(0)
if len(s) != 0 {
d, _ := time.Parse("2006-01-02 15:04:05", s)
uinx = d.Unix()
}
*t = CustTimeUinx(uinx)
return nil
}
func (t *CustTimeUinx) MarshalJSON() ([]byte, error) {
uinx := int64(*t)
quoted := strconv.Quote(time.Unix(uinx, 0).Format("2006-01-02 15:04:05"))
return []byte(quoted), nil
}
type TestItem struct {
Curr CustTimeUinx `json:"Curr"`
}
func main() {
// Unmarshal Json
s := `{"curr":"2022-06-26 10:00:00", "age":10}`
var data TestItem
json.Unmarshal([]byte(s), &data)
b, _ := json.MarshalIndent(data, "", " ")
fmt.Printf("%s\n", b)
// Marshal Json
d := TestItem{
Curr: CustTimeUinx(1656237600),
}
js, _ := json.Marshal(&d)
fmt.Printf("%s\n", js)
}
{
"Curr": 1656237600
}
{"Curr":"2022-06-26 18:00:00"}
In Python, using the uniform function is the easiest way to get a random number between a float range.
Using uniform Method
The random.uniform(a, b) method returns a random floating point number N such that a
See the following example:
#!/usr/bin/python3
# Import module
import random
a = random.uniform(1.3, 2.4)
print(a)
1.654179463181758
2.044145546151235
The end-point value b may or may not be included in the range depending on floating-point rounding in the equation a + (b-a) * random().
if you want generate a random float with N digits to the right of point, you can make this:
#!/usr/bin/python3
# Import module
import random
a = random.uniform(1.3, 2.4)
b = round(a, 4)
print(b)
2.2657
In Python, there are 2 ways to extract all the numbers contained in a string.
Using List Comprehension
List comprehensions provide a concise way to create lists.
If you only want to extract only positive integers, try the following:
#!/usr/bin/python3
s = "The 2.0L 2023 AMG C 63 Wagon"
l = [int(c) for c in s.split() if c.isdigit()]
print(l)
[2023, 63]
The other solution is:
#!/usr/bin/python3
s = "The2.0L2023AMGC63Wagon"
s = ''.join((ch if ch in '0123456789.' else ' ') for ch in s)
l = [float(i) for i in s.split()]
print(l)
[2.0, 2023.0, 63.0]
Using Regexp
A more robust version would be:
#!/usr/bin/python3
# Import module
import re
s = "The2.0L2023AM.GC63Wagon"
l = re.findall(r'[-+]?(?:\d*\.\d+|\d+)', s)
print(l)
[2023, 63]
To catch different patterns it is helpful to query with different patterns.
different number patterns'[\d]+[.,\d]+'(finds commas) 12,300 or 12,300.00'[\d]*[.][\d]+'(finds floats) 0.123 or .123'[\d]+'(finds integers) 123'[\d]+[.,\d]+|[\d]*[.][\d]+|[\d]+'(finds integers) 123'[\d]+'Combine with pipe ( | ) into one pattern with multiple or conditionals.
In Golang, using the crypto/aes package is the easiest way to encrypt a string using AES CBC.
Ehrsam, Meyer, Smith and Tuchman invented the cipher block chaining (CBC) mode of operation in 1976. In CBC mode, each block of plaintext is XORed with the previous ciphertext block before being encrypted.
Using NewCBCEncrypter Function
The cipher.NewCBCEncrypter(cipher Block) function returns returns a BlockMode which encrypts in cipher block chaining mode, using the given Block. The length of iv must be the same as the Block's block size.
The following example should cover whatever you are trying to do:
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
)
func PKCS7Padding(ciphertext []byte, blockSize, after int) []byte {
padding := (blockSize - len(ciphertext)%blockSize)
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func PKCS7Unpad(b []byte, blocksize int) ([]byte, error) {
if blocksize <= 0 {
return nil, errors.New("invalid blocksize")
}
if len(b) == 0 {
return nil, errors.New("unpad error")
}
if len(b)%blocksize != 0 {
return nil, errors.New("unpad error")
}
c := b[len(b)-1]
n := int(c)
if n == 0 || n > len(b) {
return nil, errors.New("unpad error")
}
for i := 0; i < n; i++ {
if b[len(b)-n+i] != c {
return nil, errors.New("unpad error")
}
}
return b[:len(b)-n], nil
}
func AesCBCEncrypt(key string, text string) (string, error) {
plaintext := PKCS7Padding([]byte(text), aes.BlockSize, len(text))
// CBC mode works on blocks so plaintexts may need to be padded to the
// next whole block.
if len(plaintext)%aes.BlockSize != 0 {
return "", errors.New("plaintext is not a multiple of the block size")
}
block, err := aes.NewCipher([]byte(key))
if err != nil {
return "", err
}
// The IV needs to be unique, but not secure. Therefore it's common to
// include it at the beginning of the ciphertext.
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
// It's important to remember that ciphertexts must be authenticated
// (i.e. by using crypto/hmac) as well as being encrypted in order to
// be secure.
return hex.EncodeToString(ciphertext), nil
}
func AesCBCDecrypt(key string, text string) (string, error) {
ciphertext, err := hex.DecodeString(text)
if err != nil {
return "", err
}
block, err := aes.NewCipher([]byte(key))
if err != nil {
return "", err
}
if len(ciphertext) < aes.BlockSize {
return "", errors.New("ciphertext too short")
}
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
// CBC mode always works in whole blocks.
if len(ciphertext)%aes.BlockSize != 0 {
return "", errors.New("ciphertext is not a multiple of the block size")
}
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(ciphertext, ciphertext)
// If the original plaintext lengths are not a multiple of the block
// size, padding would have to be added when encrypting, which would be
// removed at this point.
ciphertext, _ = PKCS7Unpad(ciphertext, aes.BlockSize)
return string(ciphertext[:]), nil
}
func main() {
s := "Hello"
key := "zb0SLh88rdSHswjcgcC6949ZUuopGXTt"
ciphertext, _ := AesCBCEncrypt(key, s)
fmt.Println(ciphertext)
plaintext, _ := AesCBCDecrypt(key, ciphertext)
fmt.Printf("Decrypt:: %s\n", plaintext)
}
22fb92560a7a1e7a9ba881943d5e078c517343133049b8ff4b5492a7b2276b3e
Decrypt:: Hello
In Golang, using the crypto/aes package is the easiest way to encrypt a string using AES GCM 256.
In cryptography, Galois/Counter Mode (GCM) is a mode of operation for symmetric-key cryptographic block ciphers which is widely adopted for its performance.
Using NewGCM Function
The cipher.NewGCM(cipher Block) function returns the given 128-bit, block cipher wrapped in Galois Counter Mode
with the standard nonce length.
The following example should cover whatever you are trying to do:
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/hex"
"fmt"
"io"
)
func AesGCMIv() ([]byte, error) {
// Never use more than 2^32 random nonces with a given key because of the risk of a repeat.
nonce := make([]byte, 12)
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, err
}
return nonce, nil
}
func AesGCMEncrypt(key string, text string) (string, error) {
// When decoded the key should be 16 bytes (AES-128) or 32 (AES-256).
block, err := aes.NewCipher([]byte(key))
if err != nil {
return "", err
}
plaintext := []byte(text)
nonce, err := AesGCMIv()
if err != nil {
return "", err
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
ciphertext := aesgcm.Seal(nonce, nonce, plaintext, nil)
return fmt.Sprintf("%x", ciphertext), nil
}
func AesGCMDecrypt(key string, text string) (string, error) {
// When decoded the key should be 16 bytes (AES-128) or 32 (AES-256).
block, err := aes.NewCipher([]byte(key))
if err != nil {
return "", err
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
in, _ := hex.DecodeString(text)
ns := aesgcm.NonceSize()
nonce, ciphertext := in[:ns], in[ns:]
plaintext, err := aesgcm.Open(nil, nonce, ciphertext, nil)
if err != nil {
return "", err
}
return string(plaintext[:]), nil
}
func main() {
s := "Hello"
key := "zb0SLh88rdSHswjcgcC6949ZUuopGXTt"
ciphertext, _ := AesGCMEncrypt(key, s)
fmt.Println(ciphertext)
plaintext, _ := AesGCMDecrypt(key, ciphertext)
fmt.Printf("Decrypt:: %s\n", plaintext)
}
0680f8fef173fd969bb073d614e7059b62147b0e8eb6a7fdbe3040a8cd3a0d05c5
Decrypt:: Hello
In Golang, using the crypto/hmac library is the easiest way to generate a SHA256 HMAC Hash from a string.
In cryptography, an HMAC (hash-based message authentication code) is a specific type of message authentication code (MAC) involving a cryptographic hash function and a secret cryptographic key.
Using hmac Package
The hmac.New() function returns a new HMAC hash using the given hash.Hash type and key.
The following example should cover whatever you are trying to do:
package main
import (
"crypto/hmac"
"crypto/sha256"
"fmt"
)
func main() {
s := "Hello"
key := "FDJ1mnhuzjFjTdwhq7DtZG2Cq9kuuEZCG"
h := hmac.New(sha256.New, []byte(key))
h.Write([]byte(s))
fmt.Printf("%x\n", h.Sum(nil))
fmt.Printf("%x\n", sha256.Sum256([]byte(s)))
}
b5352927e7a57a6485fa4afa7452b3817abe47d07c8aa2511bdcb9a43ac0f224
185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
Generating a MD5 HMAC Hash
For example,
package main
import (
"crypto/hmac"
"crypto/md5"
"fmt"
)
func main() {
s := "Hello"
key := "FDJ1mnhuzjFjTdwhq7DtZG2Cq9kuuEZCG"
h := hmac.New(md5.New, []byte(key))
h.Write([]byte(s))
fmt.Printf("%x\n", h.Sum(nil))
}
ed1d2af782f2fa171867e4e810bf9a3d
block length:
Hash function H
b, bytes
L, bytes
MD5
64
16
SHA-1
64
20
SHA-224
64
28
SHA-256
64
32
SHA-512/224
128
28
SHA-512/256
128
32
SHA-384
128
48
SHA-512
128
64
SHA3-224
144
28
SHA3-256
136
32
SHA3-384
104
48
SHA3-512
72
64
out = H( in )L = length( out )b = H's internal block length
In Golang, using the Sum256 function is the easiest way to get a SHA256 hash from a string. Go implements several hash functions in various crypto/* packages.
Using Sum256 Function
The sha256.Sum256() function returns the SHA256 checksum of the data.
The following example should cover whatever you are trying to do:
package main
import (
"crypto/sha256"
"encoding/hex"
"fmt"
)
func main() {
s := "Hello"
sum := sha256.Sum256([]byte(s))
fmt.Printf("%x\n", sum)
fmt.Println(hex.EncodeToString(sum[:]))
}
185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
Using New Function
New returns a new hash.Hash computing the SHA256 checksum.
For example,
package main
import (
"crypto/sha256"
"fmt"
)
func main() {
h := sha256.New()
h.Write([]byte("Hello"))
h.Write([]byte("World"))
fmt.Printf("%x\n", h.Sum(nil))
}
872e4e50ce9990d8b041330c47c9ddd11bec6b503ae9386a99da8584e9bb12c4
Generate SHA256 checksum of a file. See the following example:
package main
import (
"crypto/sha256"
"fmt"
"io"
"os"
)
func main() {
f, err := os.Open("ins.txt")
if err != nil {
// log.Fatal(err)
}
defer f.Close()
h := sha256.New()
if _, err := io.Copy(h, f); err != nil {
// log.Fatal(err)
}
fmt.Printf("%x\n", h.Sum(nil))
}
39866a50dfb27f5b96f075b3cbf9179096c87495983782427a0422c611a30e1e
In Golang, using the Sum function is the easiest way to get a MD5 hash from a string.
Using Sum Function
The md5.Sum() function returns the MD5 checksum of the data.
The following example should cover whatever you are trying to do:
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
)
func main() {
b := []byte("Hello")
out := md5.Sum(b)
fmt.Printf("%x\n", out)
// EncodeToString
fmt.Println(hex.EncodeToString(out[:]))
}
8b1a9953c4611296a827abf8c47804d7
8b1a9953c4611296a827abf8c47804d7
Using New Function
New returns a new hash.Hash computing the MD5 checksum. The Hash also implements encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to marshal and unmarshal the internal state of the hash.
For example,
package main
import (
"crypto/md5"
"fmt"
"io"
)
func main() {
h := md5.New()
io.WriteString(h, "Hello")
io.WriteString(h, "Word")
fmt.Printf("%x\n", h.Sum(nil))
}
04b6f86d49716af8d4f2edf01a309fc8
Generate MD5 checksum of a file. See the following example:
package main
import (
"crypto/md5"
"fmt"
"io"
"os"
)
func main() {
f, err := os.Open("ins.txt")
if err != nil {
// log.Fatal(err)
}
defer f.Close()
h := md5.New()
if _, err := io.Copy(h, f); err != nil {
// log.Fatal(err)
}
fmt.Printf("%x\n", h.Sum(nil))
}
3dca0fa76621281bfb7ffab47c860502
In Golang, using the IsPrivate function is the easiest way to check if IP address is in private network space.
Using IsPrivate Function
The IsPrivate() function reports whether ip is a private address, according to RFC 1918 (IPv4 addresses) and RFC 4193 (IPv6 addresses).
The following example should cover whatever you are trying to do:
// Go 1.17+
package main
import (
"fmt"
"net"
)
func main() {
ip := "1.1.1.1"
addr := net.ParseIP(ip)
fmt.Println(addr.IsPrivate())
ip = "10.3.4.0"
addr = net.ParseIP(ip)
fmt.Println(addr.IsPrivate())
}
false
true
This requires Go 1.17.
Using RFC1918
Here is an example with a list of RFC1918 address plus these others and a simple check against them as isPrivateIP(ip net.IP):
package main
import (
"fmt"
"net"
)
var privIPBlocks []*net.IPNet
func isPrivate(ip string) bool {
// init blocks
if len(privIPBlocks) == 0 {
for _, cidr := range []string{
"127.0.0.0/8", // IPv4 loopback
"10.0.0.0/8", // RFC1918
"172.16.0.0/12", // RFC1918
"192.168.0.0/16", // RFC1918
"169.254.0.0/16", // RFC3927 link-local
"::1/128", // IPv6 loopback
"fe80::/10", // IPv6 link-local
"fc00::/7", // IPv6 unique local addr
} {
_, block, err := net.ParseCIDR(cidr)
if err != nil {
panic(fmt.Errorf("parse error on %q: %v", cidr, err))
}
privIPBlocks = append(privIPBlocks, block)
}
}
addr := net.ParseIP(ip)
if addr.IsLoopback() || addr.IsLinkLocalUnicast() || addr.IsLinkLocalMulticast() {
return true
}
for _, block := range privIPBlocks {
if block.Contains(addr) {
return true
}
}
return false
}
func main() {
ip := "1.1.1.1"
fmt.Println(isPrivate(ip))
ip = "10.3.4.0"
fmt.Println(isPrivate(ip))
}
false
true
In PHP, using the $_SERVER variable is the easiest way to get the full URL.
Using $_SERVER Variable
$_SERVER is an array containing information such as headers, paths, and script locations.
The following example should cover whatever you are trying to do:
$link = "//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
// escaped
$link = htmlspecialchars($link, ENT_QUOTES, 'UTF-8');
echo $link;
//installmd.com/code/php/hash.php?p=1
In PHP, there are 2 ways to check if a string contains a specific word.
Using strpos Function
The strpos(string $haystack, string $needle, int $offset = 0): int|false function finds the numeric position of the first occurrence of needle in the haystack string. For example,
$str = "hello";
$pos = strpos($str, "l");
var_dump($pos);
$pos = strpos($str, "b");
var_dump($pos);
int(2)
bool(false)
Using preg_match Function
A simple match for are could look something like this:
$str = "hello";
$m = preg_match("/lo/i", $str);
var_dump($m);
$m = preg_match("/b/i", $str);
var_dump($m);
int(1)
int(0)