User defined function types in Go (Golang)
len()
function return if passed a UTF-8 encoded string?Length of string in Go (Golang).
do { ... } while i < 5
for _,c := range "hello" { ... }
for i := 1; i < 5; i++ { ... }
for i < 5 { ... }
Explanation: Go has only for
-loops
values := []int{1, 1, 2}
values.append(3)
values.insert(3, 3)
append(values, 3)
values = append(values, 3)
Explanation: slices in GO are immutable, so calling append
does not modify the slice
Read
?const (
Write = iota
Read
Execute
)
import "github/gin-gonic/gin"
import "https://github.com/gin-gonic/gin"
import "../template"
import "github.com/gin-gonic/gin"
package main
var GlobalFlag string
func main() {
print("["+GlobalFlag+"]")
}
GlobalFlag
was never initialized.[]
."[" +nil+"]"
is also nil
.GlobalFlag
was never initialized.myVar
accessible if it is declared outside of any functions in a file in package myPackage
located inside module myModule
?myPackage
, not the rest of myModule.myModule
.myModule
.myModule
as long as they import myPackage
Explanation: to make the variable available outside of myPackage
change the name to MyVar
.
See also an example of Exported names in the Tour of Go.
go test
to print out the tests it is running?go test
go test -x
go test --verbose
go test -v
{0, 0}
. How can you fix it?type Point struct {
x int
y int
}
func main() {
data := []byte(`{"x":1, "y": 2}`)
var p Point
if err := json.Unmarshal(data, &p); err != nil {
fmt.Println("error: ", err)
} else {
fmt.Println(p)
}
}
json.Decoder
data
X
and Y
exported (uppercase)sync.Mutex
block while it is locked?Mutex
int
and Mutex
to each and count when they return.select
statement.sync.WaitGroup
Explanation: this is exactly what sync.WaitGroup
is designed for - Use sync.WaitGroup in Golang
time.After
in a select
statement?select
statement until the time has passed.Note: it doesn’t block
select
and does not block other channels.
func Add(a, b int) int {
return a + b
}
A
// Calculate a + b
// - a: int
// - b: int
// - returns: int
func Add(a, b int) int {
return a + b
}
B
// Does a + b
func Add(a, b int) int {
return a + b
}
C
// Add returns the sum of a and b
func Add(a, b int) int {
return a + b
}
D
// returns the sum of a and b
func Add(a, b int) int {
return a + b
}
Explanation: documentation block should start with a function name
var
to compile this i := myVal.(int)?
myVal
must be an integer type, such as int
, int64
, int32
, etc.myVal
must be able to be asserted as an int
.myVal
must be an interface.myVal
must be a numeric type, such as float64
or int64
.Explanation: This kind of type casting (using .(type)
) is used on interfaces only.
//go:build windows
“Go versions 1.16 and earlier used a different syntax for build constraints, with a “// +build” prefix. The gofmt command will add an equivalent //go:build constraint when encountering the older syntax.”
data := "A group of Owls is called a parliament"
resp, err := http.Post("https://httpbin.org/post", "text/plain", []byte(data))
resp, err := http.Post("https://httpbin.org/post", "text/plain", data)
resp, err := http.Post("https://httpbin.org/post", "text/plain", strings.NewReader(data))
resp, err := http.Post("https://httpbin.org/post", "text/plain", &data)
Save() error
?switch
statement _ its own lexical block. Each case
statement _ an additional lexical blockGo Language Core technology (Volume one) 1.5-scope
Relevant excerpt from the article:
The second if statement is nested inside the first, so a variable declared in the first if statement is visible to the second if statement. There are similar rules in switch: Each case has its own lexical block in addition to the conditional lexical block.
Unmarshal
function?Relevant excerpt from the article:
To unmarshal JSON into a struct, Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match. By default, object keys which don’t have a corresponding struct field are ignored (see Decoder.DisallowUnknownFields for an alternative).
time
package’s Time.Sub()
and Time.Add()
methods?Example of Recover Function in Go (Golang)
Relevant excerpt from the article:
Recover is useful only when called inside deferred functions. Executing a call to recover inside a deferred function stops the panicking sequence by restoring normal execution and retrieves the error message passed to the panic function call. If recover is called outside the deferred function, it will not stop a panicking sequence.
println(message)
log.New(os.Stderr, "", 0).Println(message)
fmt.Errorf("%s\n", message)
fmt.Fprintln(os.Stderr, message)
go mod edit -replace example.com/greetings=../greetings
.go test all
go run --all
go test .
go test ./...
Relevant excerpt from the article:
Relative patterns are also allowed, like “go test ./…” to test all subdirectories.
Relevant excerpt from the article:
In short, Go source code is UTF-8, so the source code for the string literal is UTF-8 text.
Relevant excerpt from the article:
Package encoding defines an interface for character encodings, such as Shift JIS and Windows 1252, that can convert to and from UTF-8.
t.Fatal
different inside a t.Run
?
Fatal
is equivalent toLog
followed byFailNow
.Log
formats its arguments using default formatting, analogous toPrintln
, and records the text in the error log.FailNow
marks the function as having failed and stops its execution by callingruntime.Goexit
(which then runs all deferred calls in the current goroutine). Execution will continue at the next test or benchmark.FailNow
must be called from the goroutine running the test or benchmark function, not from other goroutines created during the test. CallingFailNow
does not stop those other goroutines.Run
runsf
as a subtest oft
called name. It runsf
in a separate goroutine and blocks untilf
returns or callst.Parallel
to become a parallel test. Run reports whetherf
succeeded (or at least did not fail before callingt.Parallel
). Run may be called simultaneously from multiple goroutines, but all such calls must return before the outer test function for t returns.
log.Fatal
do?Example of func Fatal in Go (Golang)
Relevant excerpt from the article:
Fatal
is equivalent toPrint()
followed by a call toos.Exit(1)
.
Relevant excerpt from the article:
Year: "2006" "06"
Month: "Jan" "January" "01" "1"
Day of the week: "Mon" "Monday"
Day of the month: "2" "_2" "02"
Day of the year: "__2" "002"
Hour: "15" "3" "03" (PM or AM)
Minute: "4" "04"
Second: "5" "05"
AM/PM mark: "PM"
log.Error(err)
log.Printf("error: %v", err)
log.Printf(log.ERROR, err)
log.Print("error: %v", err)
Explanation: There is defined neither log.ERROR, nor log.Error() in log package in Go; log.Print()
arguments are handled in the manner of fmt.Print()
; log.Printf()
arguments are handled in the manner of fmt.Printf()
.
go test
command recognize as test files?test
test
_test.go
_test.go
ch := make(chan int)
ch <- 7
val := <-ch
fmt.Println(val)
Go Playground share, output:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/tmp/sandbox2282523250/prog.go:7 +0x37
Program exited.
ch := make(chan int)
close(ch)
val := <-ch
fmt.Println(val)
The Go Programming Language Specification “Receive operator”, Relevant excerpt from the article:
A receive operation on a closed channel can always proceed immediately, yielding the element type’s zero value after any previously sent values have been received.
Go Playground share, output:
0
Program exited.
var stocks map[string]float64 // stock -> price
price := stocks["MSFT"]
fmt.Printf("%f\n", price)
Go Playground share, output:
0.000000
Program exited.
print Hello Gopher!
?go(fmt.Println("Hello Gopher!"))
go func() { fmt.Println("Hello Gopher!") }
go fmt.Println("Hello Gopher!")
Go fmt.Println("Hello Gopher!")
String()
stringfunc findUser(ctx context.Context, login string) (*User, error) {
ch := make(chan *User)
go func() {
ch <- findUserInDB(login)
}()
select {
case user := <-ch:
return user, nil
case <-ctx.Done():
return nil, fmt.Errorf("timeout")
}
}
Relevant excerpt from the article:
The simplest way to resolve this leak is to change the channel from an unbuffered channel to a buffered channel with a capacity of 1. Now in the timeout case, after the receiver has moved on, the Goroutine will complete its send by placing the *User value in the channel then it will return.
var i int8 = 120
i += 10
fmt.Println(i)
Go Playground example, output:
-126
Program exited.
func worker(m Message) Result
go func() {
r := worker(m)
ch <- r
}
go func() {
r := worker(m)
r -> ch
} ()
go func() {
r := worker(m)
ch <- r
} ()
go ch <- worker(m)
package os
type FilePermission int
type userID int
generate
command of the Go compiler do?sql
, json
, yaml
, and switches --schema
and --objects
to generate relevant code._generate.go
, and then compiles and runs each of these files individually.//go:generate
comments, and for each such comment runs the terminal command it specifies.mocks
and tests
to generate relevant .go
source files.Generate Go files by processing source
time.Now().Add(90)
time.Now() + (90 * time.Minute)
time.Now() + 90
time.Now().Add(90 * time.Minute)
close(ch)
immediately after wg.Wait()
.make(chan, int)
, e.g. make(chan int, 5)
.WaitGroup
calls, e.g. all lines that start with wg
.wg.Add(1)
to a line immediately before wg.Wait()
.Relevant excerpt from the article:
The simplest way to resolve this leak is to change the channel from an unbuffered channel to a buffered channel with a capacity of 1. Now in the timeout case, after the receiver has moved on, the Goroutine will complete its send by placing the *User value in the channel then it will return.
encoding/json
, how will you access the Marshal
function?encoding.json.Marshal
encoding/json.Marshal
Marshal
json.Marshal
context.Context
to implement a three-second timeout for this HTTP client making a GET request?package main
import (
"context"
"fmt"
"net/http"
)
func main() {
var cancel context.CancelFunc
ctx := context.Background()
// #1: <=== What should go here?
req, _ := http.NewRequest(http.MethodGet,
"https://linkedin.com",
nil)
// #2: <=== What should go here?
client := &http.Client{}
res, err := client.Do(req)
if err != nil {
fmt.Println("Request failed:", err)
return
}
fmt.Println("Response received, status code:",
res.StatusCode)
}
ctx.SetTimeout(3*time.Second)
req.AttachContext(ctx)
ctx, cancel = context.WithTimeout(ctx, 3*time.Second); defer cancel()
req = req.WithContext(ctx)
ctx, cancel = context.WithTimeout(ctx, 3*time.Second); defer cancel() #2: req.AttachContext(ctx)
ctx.SetTimeout(3*time.Second)
req = req.WithContext(ctx)
let Default := new Client()
public default = &Client()
var Default = &Client{}
export default := new Client{}
{Master Chief Spartan Protagonist Halo}
. How would you get it to output Master Chief - a Spartan - is the Protagonist of Halo
instead?package main
import "fmt"
type Character struct{
Name string
Class string
Role string
Game string
}
func main() {
mc := Character{
Name: "Master Chief",
Class: "Spartan",
Role: "Protagonist",
Game: "Halo",
}
fmt.Println(mc)
}
A
// Replace
// fmt.Println(mc)
// with this:
fmt.Printf("(?P<Name>) - a (?P<Class>) - is the (?P<Role>) of (?P<Game>)", mc)
B
// Replace
// fmt.Println(mc)
// with this:
fmt.Println(mc, func(c Character) string {
return c. Name + " - a " + c.Class + " - is the " + c.Role + " of " + c.Game
})
C
// add this to the package `main`
func (c Character) String() string {
return fmt.Sprintf("%s - a %s - is the %s of %s", c.Name, c.Class, c.Role,c.Game)
}
D
// add this to the package `main`
func (c Character) OnPrint() {
fmt.Println(" - a - is the of ")
}
Append()
method for Clients
?package main
type Client struct {
Name string
}
type Clients struct {
clients []*Client
}
func main() {
c:= &Clients{clients.make([]*Client,0)}
c.Append(&Client{Name: "LinkedIn API})
}
A
func (cc *Clients) Append(c *Client) {
cc.clients = append(cc.clients, c)
}
B
func (cc *Clients) Append(c *Client) {
cc.append(c)
}
C
func (cc Clients) Append(c Client) {
cc.clients = append(cc.clients, c)
}
D
func (cc *Clients) Append(c Client) {
cc.clients.append(c)
}
panic()
thrown by a called function without allowing your program to fail assuming your answer will run in the same scope where your function call will experience the panic?Wrap the function call in an anonymous function with a return type of panic
, remembering to invoke the anonymous function by suffixing it with ()
then introspecting the returned panic
instance to handle the error.
Use try{ ... }
to wrap the code calling the function and then handle the error within the catch{ ... }
.
Use defer func { ... }()
before the function call with the error and then handle the panic inside the anonymous function.
Prefix the function call with @
to force return the panic as an error
value and then handle the error just as you would an error
returned by any function.
var n int
fmt.Println (n)
This is because in Go, when a variable is declared but not explicitly initialized, it is assigned a default zero value based on its type. For integers like n, the zero value is 0.
In Go, the %s verb is used to format a string. When used with a custom type that has a String() method defined, the String() method will be automatically called and its return value will be used in the formatted string.
According to the documentation, the value 1 and 01 will represent the current month.
each layout string is a representation of the time stamp,
Jan 2 15:04:05 2006 MST
An easy way to remember this value is that it holds, when presented in this order, the values (lined up with the elements above):
1 2 3 4 5 6 -7
This syntax creates a variable _ with the type of JSONConverter and assigns to it a value of (*Namespace)(nil). This essentially checks that the Namespace struct satisfies the JSONConverter interface by ensuring that it can be assigned to a variable of type JSONConverter.
In Go, a type automatically satisfies an interface if it implements all the methods of that interface. There is no need to explicitly declare that a struct implements an interface using a specific keyword.
===[Output]================
1: &{GameId:1 Title:Wolfenstein YearReleased:1992}
2: &{GameId:2 Title:Doom YearReleased:1993}
3: &{GameId:3 Title:Quake YearReleased:1996}
===[main.go]================
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
)
type Game struct {
GameId int
Title string
YearReleased int
}
func main() {
conn, err := sql.Open("mysql",
"john_carmack:agiftw!@tcp(localhost:3306)/idsoftware")
if err != nil {
panic(err)
}
defer func() { _ = conn.Close() }()
results, err := conn.Query("SELECT game_id,title,year_released FROM games;")
if err != nil {
panic(err)
}
defer func() { _ = results.Close() }()
// #1 <=== What goes here?
for results.Next() {
var g Game
// #2 <=== What goes here?
if err != nil {
panic(err)
}
// #3 <=== What goes here?
}
for i, g := range games {
fmt.Printf("%d: %+v\n", i, g)
}
}
#1: games := make([]*Game, results.RowsAffected())
#2: g, err = results.Fetch()
#3: games[results.Index()] = &g
#1: games := []Game{}
#2: g, err = results.Fetch()
#3: games = append(games,g)
#1: games := map[int]Game{}
#2: err = results.Scan(&g)
#3: games[g.GameId] = g
#1: games := make(map[int]*Game, 0)
#2: err = results.Scan(&g.GameId, &g.Title, &g.YearReleased)
#3: games[g.GameId] = &g
be stored in a /test/
subdirectory of that package
functions accepting a testing.Tester
parameter
writing functions with names matching ^Subtest
calling testing.AssertionFailed
end in _test.go
function names matching ^Test[A-Z]
calling t.Run()
calling t.Errorf()
begin with test_
functions matching [a-z]Test$
calling testing.Subtest()
allowing testing.Assert()
to fail its assertion
be stored in /test/
root subdirectory for the project
functions accepting a testing.Test
parameter
passing closures to testing.AddSubtest()
returning an error
from the function
Relevant excerpt from the article:
The Go language defines the word rune as an alias for the type int32, so programs can be clear when an integer value represents a code point.
x, err := myFunc()
If a string variable has been allocated but not assigned a value, its default value is an empty string “”. In Go, uninitialized string variables are automatically assigned the zero value for their respective type, which for strings is an empty string.
The built-in function used to stop a program from continuing is
panic()
. Whenpanic()
is called, it triggers a panic, which stops the normal execution flow of the program and begins panicking. If the panic is not recovered, the program terminates.
a,b := 1, 2
b,c:= 3, 4
fmt.Println(a, b, c)
[ ] |
func
lambda
func()
anonymous
Explanation: they can be defined inline where they are used, offering more flexibility in code organization.
functionName(){}
call functionName(){}
func(){}()
execute func(){}
all named types not built-in to Go, such as type Example int but not int, type Example struct{...} but not struct, etc.
only types named struct, map, and slice, such as type Example struct{…}
only types named struct, such as type Example struct{...}
all types
Methods can be defined for any named type that is not a built-in type. When you create a new type using a type declaration, it becomes a named type, and you can define methods specific to that type. However, methods cannot be directly attached to built-in types like int, string, etc. reference