Go
Resources
Notes
-
workspace (mono-repos) > module (dir with
go.modfile) > package (related.gofiles) -
Builtin functions: golang.org/pkg/builtin
How to
Read from console/terminal
ip := bufio.NewReader(os.Stdin)
fmt.Print("Enter something: ")
name, _ := ip.ReadString('\n')
fmt.Println("You entered: ", name)
Use the regexp package
// Quick match
matched, err := regexp.MatchString(`foo.*`, "seafood")
fmt.Println(matched, err)
// Find a string
re := regexp.MustCompile(`foo.?`)
fmt.Printf("%q\n", re.FindString("seafood fool"))
// Find capture groups
re := regexp.MustCompile(`a(x*)b`)
fmt.Printf("%q\n", re.FindAllStringSubmatch("-ab-", -1))
fmt.Printf("%q\n", re.FindAllStringSubmatch("-axxb-", -1))
Write a Test
In short, to test a func Fn in package mx.go, create a file mx_test.go with same package, then add a TestFn function that takes in a *testing.T like so:
func TestFn(t *testing.T) {
want := "expected"
got, err := mx.Fn();
if err != nil {
t.Fatalf(err) // <- Unexpected error
}
if want != got {
t.Errorf("Expected ", want, ", got", got); // <-- Logical error
}
// Fatalf stops test run, Errorf shows error but continues other tests
// Use each where it makes sense
}
You can then test this with go test . assuming a go.mod is in place.
Compile time assertion for a type implementing an interface
TL;DR: To ensure that a type T satisfies interface I, add this one-liner:
var _ I = (*T)(nil)
Long story -
Okay, this was a bit of a head-scratcher for me, so I’ll explain it from the top as I understood it:
Premise: Go is “duck-typed” (like Python), in the sense you don’t explicitly tell a type to implement an interface (like say, Java). Rather you write the methods as required by the interface and the type satisfies that interface implicitly.
// Say we have an interface defined somewhere like so
type Xer interface { X() }
// And a function that relies on the above
func DoX(x Xer) { x.X(); }
// In some other file, we have some type
type A struct {}
// And we want to pass an instance of it
// to the function that consumes the interface
func unrelatedCall() { a := A{}; DoX(a) }
// All it takes is for the type to implement an interface is to define the behaviour
func (a A) X() {}
Problem: This is all fine and dandy when the interface definition, consumer function and the struct itself are well-known to you (like in a small code-base). You can eyeball it to ensure everything is on the up and up. When you can’t, how do you ensure and let others - humans and machines both, know as well that yes, A actually satisfies Xer and you can use it in functions that consume it?
Solution: That is where this magical line comes into play -
var _ Xer = (*A)(nil)
Alright, let’s break it down. Remember basic variable definition? var <name> <type> = <value> . Well, we don’t actually need a name because we ain’t gonna use it. So _ it. type is the interface we’re ensuring is satisfied by value. But we don’t want to initialize a value either, so we make a nil pointer to it.
And thus, if A does not implement Xer by way of X() method, we will get an error. More importantly, any packages (and linters, lsps, etc) that use A now know that it implements Xer!