Google has two tremendous problems. One of them is compile time. Back in the 1980’s, reasonable sized projects took hours to do a clean build. There were whole server farms dedicated to recompiling. You got a new "nightly build" and made modifications to that.
Google builds things that are so ridiculously huge that it’s still like that in 2017. It takes 5 hours to rebuild chrome from scratch even on a big fat i7 system. The pain of compile time on these builds hurts so much that Google has invented build tools that separate the dependency analysis and compiling, just to gain a few per cent in build time using conventional languages. Go is designed for quick compilation without the need for dependency checking, so it addresses the build pain.
Google’s other problem is string processing. Google reads and analyzes a lot of web pages, which are text files. They do a lot of string manipulation, so it pays for this to be really efficient. Google built a rich library of string functions into Go, Garbage collecting makes strings in Go simple to think about, and efficient in ways some other string libraries are not (I’m talking to you, C++ committee).
Go has good concurrency support, which is essential for a language designed after 2002, and for companies who have a million servers waiting to be spun up. But it’s not breaking new ground in concurrency.
Go = C + strings + garbage collection + concurrency. If you want to build really big programs to analyze the whole freakin’ internet, Go would be a pretty good choice for you.
The Go programming language was conceived in late 2007 as an answer to some of the problems we were seeing developing software infrastructure at Google.
The computing landscape today is almost unrelated to the environment in which the languages being used, mostly C++, Java, and Python, had been created. The problems introduced by multicore processors, networked systems, massive computation clusters, and the web programming model were being worked around rather than addressed head-on.
Moreover, the scale has changed: today's server programs comprise tens of millions of lines of code, are worked on by hundreds or even thousands of programmers, and are updated literally every day. To make matters worse, build times, even on large compilation clusters, have stretched to many minutes, even hours.
Go was designed and developed to make working in this environment more productive. Besides its better-known aspects such as built-in concurrency and garbage collection, Go's design considerations include rigorous dependency management, the adaptability of software architecture as systems grow, and robustness across the boundaries between components.
References:
References:
The built-in testing
package can be used for both testing and benchmarking.
Run go test
to run tests and go test -v --bench . --benchmem
for benchmarking.
See below.
package greeting import "testing" // Define a function named HelloWorld that takes no arguments, // and returns a string. // In other words, define a function with the following signature: // HelloWorld() string func TestHelloWorld(t *testing.T) { expected := "Hello, World!" if observed := HelloWorld(); observed != expected { t.Fatalf("HelloWorld() = %v, want %v", observed, expected) } } // BenchmarkHelloWorld() is a benchmarking function. These functions follow the // form `func BenchmarkXxx(*testing.B)` and can be used to test the performance // of your implementation. They may not be present in every exercise, but when // they are you can run them by including the `-bench` flag with the `go test` // command, like so: `go test -v --bench . --benchmem` // // You will see output similar to the following: // // BenchmarkHelloWorld 2000000000 0.46 ns/op // // This means that the loop ran 2000000000 times at a speed of 0.46 ns per loop. // // While benchmarking can be useful to compare different iterations of the same // exercise, keep in mind that others will run the same benchmarks on different // machines, with different specs, so the results from these benchmark tests may // vary. func BenchmarkHelloWorld(b *testing.B) { for i := 0; i < b.N; i++ { HelloWorld() } }
Go comes with a powerful inbuilt web server.
References:
package greeting // HelloWorld adheres to the developer norm! func HelloWorld() string { return "Hello, World!" }
The commandline tool primnts plain test docs to standard output.
go doc fmt Println
TODO
Official Guide
First, host it online.
import "github.com/kylelemons/go-gypsy/yaml" ^ ^ ^ ^ | | | `-- Package name | | `-------- Project name | `------------------- Author's handle `----------------------------- Hosting site
Go >= version 1 supports subdirectories of package repositories.
The tl;dr:
export GO111MODULE=on go mod init go mod vendor # if you have vendor/ folder, will automatically integrate go build
Example generated go.mod
file:
module github.com/okeeffed/module-data-structures-go-hello-world go 1.12
Now you can run go doc module-data-structures-go-hello-world HelloWorld
to check docs for that particular package.
References from the Medium article
package main import ( "fmt" "math" ) func main() { fmt.Println(math.Exp2(10)) // 1024 }
Other examples:
import log "github.com/sirupsen/logrus"
With custom package names:
# github.com/mlowicki/main.go package main import ( "fmt" "github.com/mlowicki/b" ) func main() { fmt.Println(c.B) } # github.com/mlowicki/b/b.go package c var B = "b"
Some examples on Golang printing
package logexample import "fmt" func main() { fmt.Println("Hello, world!") fmt.Printf("there are %v apples\n", 3) fmt.Printf("Name is %v, Age is %v \n", "john", 36) }
Useful placeholders:
Placeholder | Value |
---|---|
%v | any value printed in human readable form |
%#v | print in Golang syntax |
%+v | if value is struct, also show field names |
%T | type of the value |
%% | a literaly percent sign |
Note: %T
is useful when learning Golang.
Below are useful things to know when using the language.
Read whole file:
package main import "fmt" import "io/ioutil" func main() { // read whole file myText, myErr := ioutil.ReadFile("/Users/x/filepath") if myErr != nil { panic(myErr) // panic means abort } // print it. String converts it to string fmt.Print(string(myText)) }
Read first X bytes:
package main import "fmt" import "os" // open file. read first 200 bytes. print it. var filePath = "/Users/xah/web/xahlee_info/golang/golang_read_file.html" func getHeadBytes(path string, n int) []byte { file, err := os.Open(path) // For read access. if err != nil { panic(err) } defer file.Close() headBytes := make([]byte, n) m, err := file.Read(headBytes) if err != nil { panic(err) } return headBytes[:m] } func main() { fmt.Printf("%q\n", getHeadBytes(filePath, 200)) }
First way:
package main import "io/ioutil" func main() { mytext := []byte(`mountain and river`) outpath := "xx69447.txt" err := ioutil.WriteFile(outpath, mytext, 0644) if err != nil { panic(err) } }
Second way:
package main import "fmt" import "os" var path = "xxtest.txt" var contentX = "something" func main() { var fll, err = os.Create(path) if err != nil { panic(err) } defer fll.Close() var bytesWritten, errW = fll.WriteString(contentX) if errW != nil { panic(errW) } fmt.Printf("bytes written: %v\n", bytesWritten) }
Use filepath.Walk(dir_path, process_func)
from package path/filepath
package main import ( "fmt" "os" "path/filepath" ) var myDir = "/Users/x/web/" // go thru a dir and print all file name and extension func main() { // the function that handles each file or dir var ff = func(pathX string, infoX os.FileInfo, errX error) error { // first thing to do, check error. and decide what to do about it if errX != nil { fmt.Printf("error 「%v」 at a path 「%q」\n", errX, pathX) return errX } fmt.Printf("pathX: %v\n", pathX) // find out if it's a dir or file, if file, print info if infoX.IsDir() { fmt.Printf("is dir.\n") } else { fmt.Printf(" dir: 「%v」\n", filepath.Dir(pathX)) fmt.Printf(" file name 「%v」\n", infoX.Name()) fmt.Printf(" extenion: 「%v」\n", filepath.Ext(pathX)) } return nil } err := filepath.Walk(myDir, ff) if err != nil { fmt.Printf("error walking the path %q: %v\n", myDir, err) } }
package main import "fmt" import "os" // fileExist. check if a file exist func fileExist(path string) bool { _, err := os.Stat(path) if err == nil { return true } return false } func main() { fmt.Printf("%v\n", fileExist("/Users/x/xyz.txt")) }
To make a system call, use import "os/exec"
and use var cmd = exec.Command(cmdName, arg1, arg2)
.
You then have several choices how you want to run it. The main choices are:
Command | Use |
---|---|
cmd.Output() | run it, wait, get output |
cmd.Run() | run it, wait for it to finish |
cmd.Start() | run it, don't wait err = cmd.Wait() to get result |
If you need to change dir before running the command, use os.Chdir(path)
:
package main // example of calling shell command // cd to a given dir // call ls -al // print its output import "fmt" import "os" import "os/exec" func main() { var dirToRun = "/Users/xah/web/" var err = os.Chdir(dirToRun) if err != nil { panic(err) } var cmdName = "ls" var cmd = exec.Command(cmdName, "-a", "-l") output, err := cmd.Output() if err != nil { panic(err) } fmt.Printf("%v\n", string(output)) }
Deferdefer function_name(args)
.
When this is run, the args are evaluated, but the function call is not. The function is called right before the outer function exits.
package main import "fmt" func ff(x int) int { fmt.Printf("ff called. arg is %v\n", x) return x } func main() { var x = 3 fmt.Printf("main. x is %v\n", x) defer ff(x) x = 4 fmt.Printf("main. x is %v\n", x) } // main. x is 3 // main. x is 4 // ff called. arg is 3
Defer is used similar to “finally” in other languages, to do some clean up.
Usually, it's used right after the file opening call, to close a file.
package main import "fmt" func CopyFile(dstName, srcName string) (written int64, err error) { src, err := os.Open(srcName) if err != nil { return } defer src.Close() dst, err := os.Create(dstName) if err != nil { return } defer dst.Close() return io.Copy(dst, src) } // 2018-08-26 code from // https://blog.golang.org/defer-panic-and-recover func main() {}
[TODO]
Not all need to be done (pending what the language is useful for), but here are some useful ideas to get familiar with packages and testing for real world uses: