Learning to Write Go – Jeffrey Hulten – Using Packages



Learning to Write Go – Jeffrey Hulten – Using Packages

1 4


presentation-learning-golang

My Learning to Write Golang presenation

On Github jhulten / presentation-learning-golang

Learning to Write Go

Jeffrey Hulten

Who Am I

Jeffrey Hulten

Engineering Manager

Developer Tools

Whitepages, Inc.

What I'm Going to Cover

Assuming you know something like Python, Java, Ruby...

Using Packages Types, Structs, and Interfaces The Goroutine Channels

Not For You? Parting Hint...

Google for "golang", not "go".http://lmgtfy.com/?q=golang

Simplicity

Rich Hickey - Creator of Clojure

http://www.infoq.com/presentations/Simple-Made-Easy We program with constructs[...] but we are in a business of artifacts.

Go is a language for concurrency

Hello, Playground!

http://play.golang.org/

package main

import "fmt"

func main() {
  fmt.Println("Hello, playground")
}

Declare the package for this file

Import the fmt package (stdlib)

Declares the main function to execute

Calls Println from the fmt package

Using Packages

Standard Packages

External Packages

        package main

import (
  "fmt"
  "code.google.com/p/gcfg"
)

type Config struct {
  Section struct {
    Name string
    Flag bool
  }
}

func main() {
  var cfg Config
  err := gcfg.ReadFileInto(&cfg, "myconfig.gcfg")

  fmt.Println("The name is", cfg.Name)
}
        

Packaging Gimmies and Gotchas

  • Does not pin versions
  • Vendoring is recommended
  • Binaries are statically linked
  • NPM/Bundler is insufficent (Go is Different)

http://nathany.com/go-packages/

Private vs Public

package mypkg

func thisIsPrivate() {}
func ThisIsPublic() {}
        

Types

Golang is statically typed

            var I int
var myString string = "my string"
fileReader, err := os.Open("/tmp/filename")
        
http://golang.org/ref/spec#Variable_declarations

Structs

        type TinyStruct struct {
  IsTiny bool
}

t1 := TinyStruct{}
t2 := TinyStruct{true}
t3 := TinyStruct{IsTiny: false}
t3.IsTiny
        
http://golang.org/ref/spec#Struct_types

Structs

        type MyStruct struct {
  TinyStruct
  A string
  b uint32
  Nested struct {
    C io.Reader
  }
}

var ms MyStruct
ms = MyStruct{}
ms.A = "one"
ms.IsTiny = true

if ms.TinyStruct.IsTiny {...}
        

Structs

type OtherStruct struct {
  MStruct MyStruct
  OtherField string
}

os := OtherStruct{MStruct : MyStruct{IsTiny: false}, OtherField : "thing"}

Functions

func FunctionName(argument string, arg1, arg2 int64) {...}
func FunctionName(values ...int) error {...}
func FunctionName()(namedReturn int) {...}
var f := func() {...}
        
http://golang.org/ref/spec#Function_declarations

Interfaces and Methods

type Thinger interface {
  DoThing() error
}

func (ms MyStruct)DoThing() error {
  return nil
}

func (os *OtherStruct)DoThing() error {
  return nil
}

func ProcessThinger(t Thinger) error {
  return t.DoThing()
}
http://golang.org/ref/spec#Interface_typeshttp://golang.org/ref/spec#Method_declarations

Empty Interface is an Any Type

Goroutines

Sidenote: Concurrency vs Parallelism

Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once. -- Andrew Gerrand

More Information: Rob Pike on Concurrency vs Parallelismhttp://vimeo.com/49718712

Pike is one of the three co-creators of GoLang

How to Create a Goroutine

Call a standard function

      go time.Sleep(100 * time.Hour)
        

Call a function variable

f := func() {time.Sleep(100 * time.Hour)}
go f()

Call an anonymous function

  go func() {time.Sleep(100 * time.Hours())}()
        

Goroutine Gotchas

  • Goroutines do not block the main thread from exiting.
  • You must manage concurrent access. See sync.Mutex
  • There is no one to return a value to. (Use channels.)

Channels

  • A type.
  • A strongly typed, bounded queue for passing data between goroutines.
  • Argument types can include direction (inbound vs. outbound).

http://blog.golang.org/pipelines

Make a Channel

var ch chan int
ch = make(chan int)

Size a Channel

ch := make(chan int, 10)

Send To a Channel

ch := make(chan int, 1)
ch <- 1
ch <- 2

Recieve From a Channel

c := <-ch

Recieve From a Channel with range

ch := make(chan int, 10)
ch <- 1
ch <- 2
ch <- 3
ch <- 4
for n := range ch {
  fmt.Println(n * n)
}

Recieve From a Channel with select

ch := make(chan int, 10)
done := make(chan bool)
ch <- 1
ch <- 2
done <- true
ch <- 4

select {
  case <-done:
    return
  case n <- ch:
    fmt.Println(n * n)
}

Return a Channel

func generate(nums ...int) <-chan int {
  out := make(chan int)
  go func() {
    for _, n := range nums {
      out <- n
    }
    close(out)
  }()
  return out
}

Pass a Channel

func sq(in <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        for n := range in {
            out <- n * n
        }
        close(out)
    }()
    return out
}

A Pipeline of Channels

func square(in <-chan int) <-chan int {}
func generate(nums ...int) <-chan int {}

func main() {
  for n := range square( square( generate( 2, 3, 4 ))) {
    fmt.Println(n)
  }
}

Common Toolchain, Common Practices

  • go clean
  • go get
  • go fmt
  • go test
  • go build

go clean

  • Removes object files from package source directories.
go clean [packages]
go clean github.com/goraft/raft

go get

  • Downloads and installs packages and their dependencies.
go get [-u] [packages]
go get code.google.com/p/gcfg
go get -u github.com/goraft/raft

go fmt

  • Reformats the packages listed to the golang standard.
  • Many editors run go fmt on save.
go fmt [-n] [-x] [packages]

go build

  • Compiles the packages named by the import paths, along with their dependencies.
  • Does not install the resulting binaries.
go build [-o output] [build flags] [packages]
go build ./...

go test

  • Recompiles each package along with any files with names matching *_test.go.
    go test [-c] [-i] [build/test flags] [packages] [flags for test binary]
    go test ./...
    go test github.com/goraft/raft
  • Prints a summary of test results.
              ok   archive/tar   0.011s
    FAIL archive/zip   0.022s
    ok   compress/gzip 0.033s
    ...
              
  • Can contain test functions, benchmark functions, and example functions.

http://golang.org/pkg/testing/

go install

  • Compiles and installs packages and their dependencies.
go install [build flags] [packages]
go install github.com/crosbymichael/skydock

Top Three Hints

Don't think in traditional objects. Add behavior (interfaces) instead. Try the standard library first.Especially "net/http". Learn to love channels.

Resources

Questions?

jhulten@whitepages.com

twitter: @jhulten

We are hiring!

http://jobvite.com/m?38ZeLgwR