akuchling: Sherlock Hemlock (Default)
Every Go file starts with "package <pkgname>".

package main

func main () {

QUESTION: are braces ever optional?

Variables are declared as: var <name> <type> = <value>, e.g. var a string = "foo".

Or, automatically infer the type: a := "foo"

Basic types: int, uint.  int{8,16,32,64}, uint{8,16,32,64}.  uintptr.  float32, float64, complex32, complex64.  string.  There are no default numeric conversions.  (QUESTION: how do you do conversions?)  (QUESTION: is there a library for a decimal type?)

Data structures: array (fixed-size; like C arrays; rarely seen in APIs); slice (views into arrays; used like Python lists; widely used); map (like a dict); struct; pointer; function; interface; channel.

Type aliases:  type Prefix string

Structures: type Prefix struct { content string, n int }

Creating a structure: S = &Prefix("s", 1) or Prefix{content: "s", n: 1}.

Types also follow the function name:

func <name>(<params>) <type> { ... }

Defining methods: 
func (self *Prefix) Fix(...) { ... }

Invoked as prefix.Fix(...).  Go convention isn't to use 'self', but to use something relevant to the type, e.g. 'pref' for 'Prefix'.  Can attach methods to any user-defined type, even ones that are just alias for 'int32'.

Visibility: methods beginning w/ capital letters (e.g. Printf) are public.  Lowercase letters signal private,  (QUESTION: is this just methods, or also struct variables?)

OO-like features: there is no idea of inheritance.  Instead there's a short-cut for doing composition:

type User3 {
  uid Uid   // regular field
  PrivilegeSet // anonymous field

All of the methods of the anonymous PrivilegeSet will be available as methods of User3; Go will automatically construct wrappers or forward them.

Interface definitions:

type PrivilegeSet interface {
  HasPrivilege (name string) bool
  AddPrivilege (name string)

Control flow

C-like statements: if, for, switch.

No 'while'; write 'for { ... }' instead.  No exceptions: use multiple return values (see below).

Functions are first-class and support closures.

No try...finally: instead, use 'defer'.  e.g.  f, err := os.Open(...) ; defer f.close() .  f.close() will be executed on leaving the function.

Panic/recover: more like exception-raising, but only to be used for serious problems (e.g. out of memory).  panic(value) triggers a panic; calls deferred functions up the call stack.  These functions can call recover() and will get the value passed to panic().

Error handling: functions can return multiple values (QUESTION: just 2-tuples, or arbitrary N-tuples?)

passwd, err := io.ReadFile(...)
if (err != nil) {
  return false, fmt.Errorf("Impossible error: %s", err)
return true, nil  // No error

Can use '_' as the don't-care value, e.g. _, err = something().

Channels: act like typed pipes:

function Flying(res chan bool) {
 res <- true     // Sends the value 'true' down the pipe.
 res <- false

pipe := make(chan bool, 5)   // type of channel is 'bool'; 5 is size of queue or something
go Flying(pipe)       // Starts a goroutine running the function Flying().
result <- pipe   // Reads a value from the channel; will block if value isn't ready.

Data structures: maps:  

  m := make(map[int]string)  // Maps integers to strings
  m[1] = "a"
  m[2] = "b"
  m[3] = "c"
  // Checking for an element
  S, ok := m[4]
  if !ok { ... record not found ... }
  // Looping over the content
  for k,v := range m { ... }


There's a 'testing' package that provides a testing.T interface with logging methods.  The "go test" subcommand will run tests.  Example:

package s_test
import ("testing" "string" ...)

func TestIndex(t *testing.T) {
  value = string.index("bogus", "foo")
  if (value != expected) {
     t.Errorf("Problem with index")

Other methods: t.Fatalf("...") ; t.Logf("...") to print a message with '-v'.  t.Skip("Doesn't work on ARM")

t.Parallel() marks a test as safe for parallel execution.

"go test" reports pass/fail.  "go test -cover" reports coverage.  "go test -coverprofile=cover.out" writes output to a file, and then "go tool cover -func=cover.out" will report on it.  "go cover -html=cover.out" generates an HTML visualization.

"go test -race <pkgname>" adds instrumentation for checking race conditions, and will report on problems.  "go run -race source.go" will execute a file.  "go build -race" and "go install -race" also work.

"go vet <pkgname>" is a static analyzer that reports problems.

Testing HTTP servers

There's a net/http/httptest package in the stdlib.  Usage is something like:

ts := httptest.NewServer(handler_func)
defer ts.Close()
res, err := http.Get(ts.URL)    // Accesses this test server


akuchling: Sherlock Hemlock (Default)

September 2016

2526272829 30 


RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 23rd, 2017 03:47 am
Powered by Dreamwidth Studios