Examples of Golang examples compared to Node.js for learning
This guide full of examples is intended for people learning Go that are coming from Node.js, although the vice versa can work too. This is not meant to be a complete guide and it is assumed that you've gone through the Tour of Go tutorial. This guide is meant to be barely good enough to help you at a high level understand how to do X in Y and doing further learning on your own is of course required.
- Examples
- comments
- printing
- logging
- variables
- types
- type check
- interpolation
- if/else
- for
- while
- switch
- arrays
- uint8 arrays
- array iteration
- buffers
- maps
- objects
- functions
- default values
- destructuring
- spread operator
- rest operator
- swapping
- classes
- generators
- datetime
- timeout
- interval
- IIFE
- files
- json
- big numbers
- promises
- async/await
- streams
- event emitter
- Contributing
- License
All sample code is available in examples/
// this is a line comment
/*
this is a block comment
*/
package main
func main() {
// this is a line comment
/*
this is a block comment
*/
}
console.log('print to stdout')
console.log('format %s %d', 'example', 1)
console.error('print to stderr')
Output
print to stdout
format example 1
print to stderr
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println("print to stdout")
fmt.Printf("format %s %v\n", "example", 1)
fmt.Fprintf(os.Stderr, "print to stderr")
}
Output
print to stdout
format example 1
print to stderr
console.log((new Date()).toISOString(), 'hello world')
Output
2021-04-11T20:55:07.451Z hello world
package main
import "log"
func main() {
log.Println("hello world")
}
Output
2021/04/11 13:55:07 hello world
(Package log
writes to standard error ánd prints the date and time of each logged message)
// function scoped
var foo = 'foo'
// block scoped
let bar = 'bar'
// constant
const qux = 'qux'
(variables are block scoped in Go)
package main
func main() {
// explicit
var foo string = "foo"
// type inferred
var bar = "foo"
// shorthand
baz := "bar"
// constant
const qux = "qux"
}
const name = 'bob'
const age = 21
const message = `${name} is ${age} years old`
console.log(message)
Output
bob is 21 years old
package main
import "fmt"
func main() {
name := "bob"
age := 21
message := fmt.Sprintf("%s is %d years old", name, age)
fmt.Println(message)
}
Output
bob is 21 years old
// primitives
const myBool = true
const myNumber = 10
const myString = 'foo'
const mySymbol = Symbol('bar')
const myNull = null
const myUndefined = undefined
// object types
const myObject = {}
const myArray = []
const myFunction = function() {}
const myError = new Error('error')
const myDate = new Date()
const myRegex = /a/
const myMap = new Map()
const mySet = new Set()
const myPromise = Promise.resolve()
const myGenerator = function *() {}
const myClass = class {}
package main
func main() {
// primitives
var myBool bool = true
var myInt int = 10
var myInt8 int8 = 10
var myInt16 int16 = 10
var myInt32 int32 = 10
var myInt64 int64 = 10
var myUint uint = 10
var myUint8 uint8 = 10
var myUint16 uint16 = 10
var myUint32 uint32 = 10
var myUint64 uint64 = 10
var myUintptr uintptr = 10
var myFloat32 float32 = 10.5
var myFloat64 float64 = 10.5
var myComplex64 complex64 = -1 + 10i
var myComplex128 complex128 = -1 + 10i
var myString string = "foo"
var myByte byte = 10 // alias to uint8
var myRune rune = 'a' // alias to int32
// composite types
var myStruct struct{} = struct{}{}
var myArray []string = []string{}
var myMap map[string]int = map[string]int{}
var myFunction func() = func() {}
var myChannel chan bool = make(chan bool)
var myInterface interface{} = nil
var myPointer *int = new(int)
}
function typeOf(obj) {
return {}.toString.call(obj).split(' ')[1].slice(0,-1).toLowerCase()
}
const values = [
true,
10,
'foo',
Symbol('bar'),
null,
undefined,
NaN,
{},
[],
function(){},
new Error(),
new Date(),
/a/,
new Map(),
new Set(),
Promise.resolve(),
function *() {},
class {},
]
for (value of values) {
console.log(typeOf(value))
}
Output
boolean
number
string
symbol
null
undefined
number
object
array
function
error
date
regexp
map
set
promise
generatorfunction
function
package main
import (
"fmt"
"reflect"
"regexp"
"time"
)
func main() {
values := []interface{}{
true,
int8(10),
int16(10),
int32(10),
int64(10),
uint(10),
uint8(10),
uint16(10),
uint32(10),
uint64(10),
uintptr(10),
float32(10.5),
float64(10.5),
complex64(-1 + 10i),
complex128(-1 + 10i),
"foo",
byte(10),
'a',
rune('a'),
struct{}{},
[]string{},
map[string]int{},
func() {},
make(chan bool),
nil,
new(int),
time.Now(),
regexp.MustCompile(`^a$`),
}
for _, value := range values {
fmt.Println(reflect.TypeOf(value))
}
}
Output
bool
int8
int16
int32
int64
uint
uint8
uint16
uint32
uint64
uintptr
float32
float64
complex64
complex128
string
uint8
int32
int32
struct {}
[]string
map[string]int
func()
chan bool
<nil>
*int
time.Time
*regexp.Regexp
const array = [1, 2]
if (array) {
console.log('array exists')
}
if (array.length === 2) {
console.log('length is 2')
} else if (array.length === 1) {
console.log('length is 1')
} else {
console.log('length is other')
}
const isOddLength = array.length % 2 == 1 ? 'yes' : 'no'
console.log(isOddLength)
Output
array exists
length is 2
no
package main
import "fmt"
func main() {
array := []byte{1, 2}
if array != nil {
fmt.Println("array exists")
}
if len(array) == 2 {
fmt.Println("length is 2")
} else if len(array) == 1 {
fmt.Println("length is 1")
} else {
fmt.Println("length is other")
}
// closest thing to ternary operator
isOddLength := "no"
if len(array)%2 == 1 {
isOddLength = "yes"
}
fmt.Println(isOddLength)
}
Output
array exists
length is 2
no
for (let i = 0; i <= 5; i++) {
console.log(i)
}
Output
0
1
2
3
4
5
package main
import "fmt"
func main() {
for i := 0; i <= 5; i++ {
fmt.Println(i)
}
}
Output
0
1
2
3
4
5
let i = 0
while (i <= 5) {
console.log(i)
i++
}
Output
0
1
2
3
4
5
(there's no while keyword in Go but the same functionality is achieved by using for)
package main
import "fmt"
func main() {
i := 0
for i <= 5 {
fmt.Println(i)
i++
}
}
Output
0
1
2
3
4
5
const value = 'b'
switch(value) {
case 'a':
console.log('A')
break
case 'b':
console.log('B')
break
case 'c':
console.log('C')
break
default:
console.log('first default')
}
switch(value) {
case 'a':
console.log('A - falling through')
case 'b':
console.log('B - falling through')
case 'c':
console.log('C - falling through')
default:
console.log('second default')
}
Output
B
B - falling through
C - falling through
second default
package main
import "fmt"
func main() {
value := "b"
switch value {
case "a":
fmt.Println("A")
case "b":
fmt.Println("B")
case "c":
fmt.Println("C")
default:
fmt.Println("first default")
}
switch value {
case "a":
fmt.Println("A - falling through")
fallthrough
case "b":
fmt.Println("B - falling through")
fallthrough
case "c":
fmt.Println("C - falling through")
fallthrough
default:
fmt.Println("second default")
}
}
Output
B
B - falling through
C - falling through
second default
Examples of slicing, copying, appending, and prepending arrays.
const array = [1, 2, 3, 4, 5]
console.log(array)
const clone = array.slice(0)
console.log(clone)
const sub = array.slice(2,4)
console.log(sub)
const concatenated = clone.concat([6, 7])
console.log(concatenated)
const prepended = [-2,-1,0].concat(concatenated)
console.log(prepended)
Output
[ 1, 2, 3, 4, 5 ]
[ 1, 2, 3, 4, 5 ]
[ 3, 4 ]
[ 1, 2, 3, 4, 5, 6, 7 ]
[ -2, -1, 0, 1, 2, 3, 4, 5, 6, 7 ]
package main
import "fmt"
func main() {
array := []int{1, 2, 3, 4, 5}
fmt.Println(array)
clone := make([]int, len(array))
copy(clone, array)
fmt.Println(clone)
sub := array[2:4]
fmt.Println(sub)
concatenated := append(array, []int{6, 7}...)
fmt.Println(concatenated)
prepended := append([]int{-2, -1, 0}, concatenated...)
fmt.Println(prepended)
}
Output
[1 2 3 4 5]
[1 2 3 4 5]
[3 4]
[1 2 3 4 5 6 7]
[-2 -1 0 1 2 3 4 5 6 7]
const array = new Uint8Array(10)
console.log(array)
const offset = 1
array.set([1, 2, 3], offset)
console.log(array)
const sub = array.subarray(2)
console.log(sub)
const sub2 = array.subarray(2,4)
console.log(sub2)
console.log(array)
const value = 9
const start = 5
const end = 10
array.fill(value, start, end)
console.log(array)
console.log(array.byteLength)
Output
Uint8Array [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
Uint8Array [ 0, 1, 2, 3, 0, 0, 0, 0, 0, 0 ]
Uint8Array [ 2, 3, 0, 0, 0, 0, 0, 0 ]
Uint8Array [ 2, 3 ]
Uint8Array [ 0, 1, 2, 3, 0, 0, 0, 0, 0, 0 ]
Uint8Array [ 0, 1, 2, 3, 0, 9, 9, 9, 9, 9 ]
10
package main
import "fmt"
func main() {
array := make([]uint8, 10)
fmt.Println(array)
offset := 1
copy(array[offset:], []uint8{1, 2, 3})
fmt.Println(array)
sub := array[2:]
fmt.Println(sub)
sub2 := array[2:4]
fmt.Println(sub2)
fmt.Println(array)
value := uint8(9)
start := 5
end := 10
for i := start; i < end; i++ {
array[i] = value
}
fmt.Println(array)
fmt.Println(len(array))
}
Output
[0 0 0 0 0 0 0 0 0 0]
[0 1 2 3 0 0 0 0 0 0]
[2 3 0 0 0 0 0 0]
[2 3]
[0 1 2 3 0 0 0 0 0 0]
[0 1 2 3 0 9 9 9 9 9]
10
Examples of iterating, mapping, filtering, and reducing arrays.
const array = ['a', 'b', 'c']
array.forEach((value, i) => {
console.log(i, value)
})
const mapped = array.map(value => {
return value.toUpperCase()
})
console.log(mapped)
const filtered = array.filter((value, i) => {
return i % 2 == 0
})
console.log(filtered)
const reduced = array.reduce((acc, value, i) => {
if (i % 2 == 0) {
acc.push(value.toUpperCase())
}
return acc
}, [])
console.log(reduced)
Output
0 'a'
1 'b'
2 'c'
[ 'A', 'B', 'C' ]
[ 'a', 'c' ]
[ 'A', 'C' ]
package main
import (
"fmt"
"strings"
)
func main() {
array := []string{"a", "b", "c"}
for i, value := range array {
fmt.Println(i, value)
}
mapped := make([]string, len(array))
for i, value := range array {
mapped[i] = strings.ToUpper(value)
}
fmt.Println(mapped)
var filtered []string
for i, value := range array {
if i%2 == 0 {
filtered = append(filtered, value)
}
}
fmt.Println(filtered)
var reduced []string
for i, value := range array {
if i%2 == 0 {
reduced = append(reduced, strings.ToUpper(value))
}
}
fmt.Println(reduced)
}
Output
0 a
1 b
2 c
[A B C]
[a c]
[A C]
Examples of how to sort an array
const stringArray = ['a', 'd', 'z', 'b', 'c', 'y']
const stringArraySortedAsc = stringArray.sort((a, b) => a > b ? 1 : -1)
console.log(stringArraySortedAsc)
const stringArraySortedDesc = stringArray.sort((a, b) => a > b ? -1 : 1)
console.log(stringArraySortedDesc)
const numberArray = [1, 3, 5, 9, 4, 2, 0]
const numberArraySortedAsc = numberArray.sort((a, b) => a - b)
console.log(numberArraySortedAsc)
const numberArraySortedDesc = numberArray.sort((a, b) => b - a)
console.log(numberArraySortedDesc)
const collection = [
{
name: "Li L",
age: 8
},
{
name: "Json C",
age: 3
},
{
name: "Zack W",
age: 15
},
{
name: "Yi M",
age: 2
}
]
const collectionSortedByAgeAsc = collection.sort((a, b) => a.age - b.age)
console.log(collectionSortedByAgeAsc)
const collectionSortedByAgeDesc = collection.sort((a, b) => b.age - a.age)
console.log(collectionSortedByAgeDesc)
Output
[ 'a', 'b', 'c', 'd', 'y', 'z' ]
[ 'z', 'y', 'd', 'c', 'b', 'a' ]
[ 0, 1, 2, 3, 4, 5, 9 ]
[ 9, 5, 4, 3, 2, 1, 0 ]
[ { name: 'Yi M', age: 2 },
{ name: 'Json C', age: 3 },
{ name: 'Li L', age: 8 },
{ name: 'Zack W', age: 15 } ]
[ { name: 'Zack W', age: 15 },
{ name: 'Li L', age: 8 },
{ name: 'Json C', age: 3 },
{ name: 'Yi M', age: 2 } ]
package main
import (
"fmt"
"sort"
)
type Person struct {
Name string
Age int
}
type PersonCollection []Person
func (pc PersonCollection) Len() int {
return len(pc)
}
func (pc PersonCollection) Swap(i, j int) {
pc[i], pc[j] = pc[j], pc[i]
}
func (pc PersonCollection) Less(i, j int) bool {
// asc
return pc[i].Age < pc[j].Age
}
func main() {
intList := []int{1, 3, 5, 9, 4, 2, 0}
// asc
sort.Ints(intList)
fmt.Println(intList)
// desc
sort.Sort(sort.Reverse(sort.IntSlice(intList)))
fmt.Println(intList)
stringList := []string{"a", "d", "z", "b", "c", "y"}
// asc
sort.Strings(stringList)
fmt.Println(stringList)
// desc
sort.Sort(sort.Reverse(sort.StringSlice(stringList)))
fmt.Println(stringList)
collection := []Person{
{"Li L", 8},
{"Json C", 3},
{"Zack W", 15},
{"Yi M", 2},
}
// asc
sort.Sort(PersonCollection(collection))
fmt.Println(collection)
// desc
sort.Sort(sort.Reverse(PersonCollection(collection)))
fmt.Println(collection)
}
Output
[0 1 2 3 4 5 9]
[9 5 4 3 2 1 0]
[a b c d y z]
[z y d c b a]
[{Yi M 2} {Json C 3} {Li L 8} {Zack W 15}]
[{Zack W 15} {Li L 8} {Json C 3} {Yi M 2}]
Examples of how to allocate a buffer, write in big or little endian format, encode to a hex string, and check if buffers are equal.
const buf = Buffer.alloc(6)
let value = 0x1234567890ab
let offset = 0
let byteLength = 6
buf.writeUIntBE(value, offset, byteLength)
let hexstr = buf.toString('hex')
console.log(hexstr)
const buf2 = Buffer.alloc(6)
value = 0x1234567890ab
offset = 0
byteLength = 6
buf2.writeUIntLE(value, offset, byteLength)
hexstr = buf2.toString('hex')
console.log(hexstr)
let isEqual = Buffer.compare(buf, buf2) === 0
console.log(isEqual)
isEqual = Buffer.compare(buf, buf) === 0
console.log(isEqual)
Output
1234567890ab
ab9078563412
false
true
package main
import (
"bytes"
"encoding/binary"
"encoding/hex"
"fmt"
"log"
"math/big"
"reflect"
)
func writeUIntBE(buffer []byte, value, offset, byteLength int64) {
slice := make([]byte, byteLength)
val := new(big.Int)
val.SetUint64(uint64(value))
valBytes := val.Bytes()
buf := bytes.NewBuffer(slice)
err := binary.Write(buf, binary.BigEndian, &valBytes)
if err != nil {
log.Fatal(err)
}
slice = buf.Bytes()
slice = slice[int64(len(slice))-byteLength : len(slice)]
copy(buffer[offset:], slice)
}
func writeUIntLE(buffer []byte, value, offset, byteLength int64) {
slice := make([]byte, byteLength)
val := new(big.Int)
val.SetUint64(uint64(value))
valBytes := val.Bytes()
tmp := make([]byte, len(valBytes))
for i := range valBytes {
tmp[i] = valBytes[len(valBytes)-1-i]
}
copy(slice, tmp)
copy(buffer[offset:], slice)
}
func main() {
buf := make([]byte, 6)
writeUIntBE(buf, 0x1234567890ab, 0, 6)
fmt.Println(hex.EncodeToString(buf))
buf2 := make([]byte, 6)
writeUIntLE(buf2, 0x1234567890ab, 0, 6)
fmt.Println(hex.EncodeToString(buf2))
isEqual := reflect.DeepEqual(buf, buf2)
fmt.Println(isEqual)
isEqual = reflect.DeepEqual(buf, buf)
fmt.Println(isEqual)
}
Output
1234567890ab
ab9078563412
false
true
const map = new Map()
map.set('foo', 'bar')
let found = map.has('foo')
console.log(found)
let item = map.get('foo')
console.log(item)
map.delete('foo')
found = map.has('foo')
console.log(found)
item = map.get('foo')
console.log(item)
const map2 = {}
map2['foo'] = 'bar'
item = map2['foo']
delete map2['foo']
const map3 = new Map()
map3.set('foo', 100)
map3.set('bar', 200)
map3.set('baz', 300)
for (let [key, value] of map3) {
console.log(key, value)
}
Output
true
bar
false
undefined
foo 100
bar 200
baz 300
package main
import "fmt"
func main() {
map1 := make(map[string]string)
map1["foo"] = "bar"
item, found := map1["foo"]
fmt.Println(found)
fmt.Println(item)
delete(map1, "foo")
item, found = map1["foo"]
fmt.Println(found)
fmt.Println(item)
map2 := make(map[string]int)
map2["foo"] = 100
map2["bar"] = 200
map2["baz"] = 300
for key, value := range map2 {
fmt.Println(key, value)
}
}
Output
true
bar
false
foo 100
bar 200
baz 300
const obj = {
someProperties: {
'foo': 'bar'
},
someMethod: (prop) => {
return obj.someProperties[prop]
}
}
let item = obj.someProperties['foo']
console.log(item)
item = obj.someMethod('foo')
console.log(item)
Output
bar
bar
package main
import "fmt"
type Obj struct {
SomeProperties map[string]string
}
func NewObj() *Obj {
return &Obj{
SomeProperties: map[string]string{
"foo": "bar",
},
}
}
func (o *Obj) SomeMethod(prop string) string {
return o.SomeProperties[prop]
}
func main() {
obj := NewObj()
item := obj.SomeProperties["foo"]
fmt.Println(item)
item = obj.SomeMethod("foo")
fmt.Println(item)
}
Output
bar
bar
< 735 div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function add(a, b) { return a + b } const result = add(2,3) console.log(result)">
function add(a, b) { return a + b } const result = add(2,3) console.log(result)