Jupyter Notebook Viewer (original) (raw)
Environments¶
Displays the environment where this notebook is executed.
In [ ]:
import ( "fmt" "os" "os/user" "runtime" )
{ user, _ := user.Current() fmt.Printf("Go: %s (%s_%s)\n", runtime.Version(), runtime.GOOS, runtime.GOARCH) fmt.Printf("User: %s\n", user.Username) wd, _ := os.Getwd() fmt.Printf("Working dir: %s\n", wd) fmt.Printf("NumCPU: %d\n", runtime.NumCPU()) }
Go: go1.9.2 (linux_amd64) User: gopher Working dir: /examples NumCPU: 2
Simple functions¶
In [ ]:
// naiveFib calculates the n-th fibonacci number func naiveFib(n int) int { if n > 1 { return naiveFib(n - 1) + naiveFib(n - 2) } return 1 }
if, for, etc..¶
In [ ]:
import "fmt"
n := 10
if n > 0 { fmt.Println("n is positive:", n) } else { fmt.Println("n is not positive:", n) }
In [ ]:
sum := 0 for i := 1; i <= n; i++ { sum += i } sum
In [ ]:
switch sum { case 55: fmt.Println("OK") default: fmt.Println("Fail") }
Use standard libraries¶
In [ ]:
fmt.Printf("sin(pi/3) == %f\n", math.Sin(math.Pi/3)) fmt.Printf("cos(pi/3) == %f\n", math.Cos(math.Pi/3)) fmt.Printf("sqrt(3)/2 == %f\n", math.Sqrt(3)/2) fmt.Printf("log(e^2) == %f\n", math.Log(math.E * math.E))
sin(pi/3) == 0.866025 cos(pi/3) == 0.500000 sqrt(3)/2 == 0.866025 log(e^2) == 2.000000 21
Non-deterministic code¶
In [ ]:
import ( "math/rand" "time" )
In [ ]:
rand.Seed(time.Now().UnixNano()) r := rand.Int() r
In [ ]:
start := time.Now() start
2017-10-16 13:17:47.637999781 +0000 UTC m=+6.138424087
2017-10-16 13:17:48.311503905 +0000 UTC m=+6.811928266
In [ ]:
fmt.Printf("end - start = %v", end.Sub(start))
end - start = 673.504179ms26
struct and interface¶
In [ ]:
type person struct { name string age int }
func (p *person) Hello() string { return fmt.Sprintf("Hello! Name: %s, Age: %d", p.name, p.age) }
In [ ]:
p := person{"Alice", 12} fmt.Printf("p.name = %q\n", p.name) fmt.Printf("p.Hello() == %q\n", p.Hello())
p.name = "Alice" p.Hello() == "Hello! Name: Alice, Age: 12" 43
In [ ]:
type hello interface { Hello() string }
func printHello(h hello) { if _, ok := h.(*person); ok { fmt.Println("h is *person") } fmt.Printf("h.Hello() == %q\n", h.Hello()) }
p := person{"Alice", 12} printHello(&p)
h is *person h.Hello() == "Hello! Name: Alice, Age: 12"
Go libraries and interfaces¶
Of course, you can interacts with Go libraries using interfaces
In [ ]:
// You can pass a type defined in lgo as an interface defined in Go.
import ( "bytes" "fmt" "io" )
type myReader struct { content string idx int }
func (r *myReader) Read(p []byte) (n int, err error) { if len(p) == 0 { return 0, nil } if r.idx >= len(r.content) { return 0, io.EOF } p[0] = r.content[r.idx] fmt.Printf("Read %q\n", r.content[r.idx]) r.idx++ return 1, nil }
{ r := myReader{content: "Hello!"} var buf bytes.Buffer io.Copy(&buf, &r) fmt.Printf("buf == %q\n", buf.String()) }
Read 'H' Read 'e' Read 'l' Read 'l' Read 'o' Read '!' buf == "Hello!"
In [ ]:
// You can pass a struct defined in Go as an interface defined in lgo too.
import ( "bytes" "fmt" )
type withLen interface { Len() int }
func printLen(l withLen) { fmt.Printf("Len(%v) == %d\n", l, l.Len()) }
{ var buf bytes.Buffer buf.WriteString("01234") printLen(&buf) buf.WriteString("56789") printLen(&buf) }
Len(01234) == 5 Len(0123456789) == 10
return & defer¶
A code block in lgo is executed code inside a function with no return value. You can exit code by return statement. Also, you can use defer to execute functions after a code block.
In [ ]:
// return if true { fmt.Println("return!") return } fmt.Println("continue!")
In [ ]:
fmt.Println("start") defer fmt.Println("defer (1)") defer fmt.Println("defer (2)") fmt.Println("end")
start end 4 defer (2) defer (1)
channel and goroutine¶
In [ ]:
import "fmt"
{ done := make(chan struct{}) ch := make(chan int) // producer go func(){ for i := 0; i < 10; i++ { ch <- i * i } close(ch) }() // consumer go func() { for i := range ch { fmt.Printf("i == %d\n", i) } close(done) }() <-done }
i == 0 i == 1 i == 4 i == 9 i == 16 i == 25 i == 36 i == 49 i == 64 i == 81
panic¶
panic: failed!
goroutine 41 [running]: runtime/debug.Stack(0xc400000008, 0x7f257d12a338, 0xc4204301a0) /usr/lib/go-1.9/src/runtime/debug/stack.go:24 +0xa9 github.com/yunabe/lgo/core.(*resultCounter).recordResult(0xc420430188, 0x7f257cf4f140, 0x7f25705f3970) /home/yunabe/local/gocode/src/github.com/yunabe/lgo/core/core.go:182 +0xce github.com/yunabe/lgo/core.(*resultCounter).recordResultInDefer(0xc420430188) /home/yunabe/local/gocode/src/github.com/yunabe/lgo/core/core.go:187 +0x3b panic(0x7f257cf4f140, 0x7f25705f3970) /usr/lib/go-1.9/src/runtime/panic.go:491 +0x294 github.com/yunabe/lgo/sess7b2274696d65223a313531333332343933303133383031353930307d/exec3.lgo_init() /home/yunabe/local/gocode/src/github.com/yunabe/lgo/sess7b2274696d65223a313531333332343933303133383031353930307d/exec3/src.go:6 +0x40 github.com/yunabe/lgo/cmd/runner.loadShared.func3() /home/yunabe/local/gocode/src/github.com/yunabe/lgo/cmd/runner/runner.go:60 +0x26 github.com/yunabe/lgo/core.newRoutineManager.func1(0xc420430180, 0xc42042aad0) /home/yunabe/local/gocode/src/github.com/yunabe/lgo/core/core.go:205 +0x83 created by github.com/yunabe/lgo/core.newRoutineManager /home/yunabe/local/gocode/src/github.com/yunabe/lgo/core/core.go:202 +0xc5 main routine failed
In [ ]:
go func() { panic("goroutine failed") }()
panic: goroutine failed
goroutine 67 [running]: runtime/debug.Stack(0xc400000008, 0x7f257d12a338, 0xc4204181c0) /usr/lib/go-1.9/src/runtime/debug/stack.go:24 +0xa9 github.com/yunabe/lgo/core.(*resultCounter).recordResult(0xc4204181a8, 0x7f257cf4f140, 0x7f25703ef760) /home/yunabe/local/gocode/src/github.com/yunabe/lgo/core/core.go:182 +0xce github.com/yunabe/lgo/core.FinalizeGoroutine(0xc42032e2c0) /home/yunabe/local/gocode/src/github.com/yunabe/lgo/core/core.go:283 +0x4f panic(0x7f257cf4f140, 0x7f25703ef760) /usr/lib/go-1.9/src/runtime/panic.go:491 +0x294 github.com/yunabe/lgo/sess7b2274696d65223a313531333332343933303133383031353930307d/exec4.lgo_init.func1.1() /home/yunabe/local/gocode/src/github.com/yunabe/lgo/sess7b2274696d65223a313531333332343933303133383031353930307d/exec4/src.go:12 +0x40 github.com/yunabe/lgo/sess7b2274696d65223a313531333332343933303133383031353930307d/exec4.lgo_init.func1(0xc42032e2c0) /home/yunabe/local/gocode/src/github.com/yunabe/lgo/sess7b2274696d65223a313531333332343933303133383031353930307d/exec4/src.go:13 +0x4a created by github.com/yunabe/lgo/sess7b2274696d65223a313531333332343933303133383031353930307d/exec4.lgo_init /home/yunabe/local/gocode/src/github.com/yunabe/lgo/sess7b2274696d65223a313531333332343933303133383031353930307d/exec4/src.go:8 +0x4a 1 goroutine failed
reflect¶
reflect package works with lgo properly. Note that unexported fields are renamed with LgoExport_ prefix in lgo.
In [ ]:
import ( "reflect" )
type person struct { Name string Age int secret string }
func (p *person) GetSecret() string { return p.secret }
p := &person{Name:"Alice", Age: 12, secret: "1234"}
In [ ]:
{ t := reflect.TypeOf(p) fmt.Println("--- fields ---") for i := 0; i < t.Elem().NumField(); i++ { fmt.Printf("field[%d] = %s\n", i, t.Elem().Field(i).Name) }
fmt.Println("--- methods ---")
for i := 0; i < t.NumMethod(); i++ {
fmt.Printf("method[%d] = %s\n", i, t.Method(i).Name)
}
// Set "Age" via reflect.
v := reflect.ValueOf(p)
v.Elem().Field(1).Set(reflect.ValueOf(34))
fmt.Println("------------")
fmt.Printf("p == %#v\n", p)}
--- fields --- field[0] = Name field[1] = Age field[2] = LgoExport_secret --- methods --- method[0] = GetSecret
p == &lgo_exec.LgoExport_person{Name:"Alice", Age:34, LgoExport_secret:"1234"}
Display¶
To display non-text content like HTML, MarkDown and images, use _ctx.Display.
In [ ]:
// Display HTML _ctx.Display.HTML( `Hello lgo: GitHub lgo
`, nil)In [ ]:
import (
"fmt"
"io/ioutil"
"net/http"
)
var gopherPNG []byte { res, err := http.Get("https://golang.org/doc/gopher/frontpage.png") if err != nil { fmt.Printf("Failed to get: %v\n", err) return } defer res.Body.Close() gopherPNG, err = ioutil.ReadAll(res.Body) if err != nil { fmt.Printf("Failed to read: %v\n", err) return } _ctx.Display.Text("PNG Gopher", nil) _ctx.Display.PNG(gopherPNG, nil) }
In [ ]:
import ( "bytes" "image" jpeg "image/jpeg" _ "image/png" "os"
"github.com/nfnt/resize")
{ img, _, err := image.Decode(bytes.NewBuffer(gopherPNG)) if err != nil { fmt.Fprintf(os.Stderr, "Failed to decode: %v", err) return } img = resize.Resize(100, 0, img, resize.Lanczos3) var buf bytes.Buffer jpeg.Encode(&buf, img, &jpeg.Options{Quality: 1}) _ctx.Display.Text("Resized and highly compressed JPEG", nil) _ctx.Display.JPEG(buf.Bytes(), nil) }
Resized and highly compressed JPEG
Display ID¶
You can use the second paramter of display methods to overwrite the existing results. See DataDisplayer for details.
In [ ]:
import ( "bytes" "fmt" "image" png "image/png" jpeg "image/jpeg" "os" "time"
"github.com/nfnt/resize")
{ img, err := png.Decode(bytes.NewBuffer(gopherPNG)) if err != nil { fmt.Fprintf(os.Stderr, "Failed to decode:", err) return } img = resize.Resize(100, 0, img, resize.Lanczos3) var labelID, imgID string for quality := 25; quality > 0; quality -= 1 { var buf bytes.Buffer jpeg.Encode(&buf, img, &jpeg.Options{Quality: quality}) size := float32(len(buf.Bytes()))/1000 _ctx.Display.Text(fmt.Sprintf("Quality: %d\nSize: %.2fkB", quality, size), &labelID) _ctx.Display.JPEG(buf.Bytes(), &imgID) time.Sleep(200*time.Millisecond) } }
Compile errors¶
syntax errors¶
In [ ]:
{ x := 10 + 3.4 + } { for i := 0 {} }
3:1: expected operand, found '}' 5:5: expected ';', found 'for'
type errors¶
In [ ]:
{ // L.1 a := undefined
x := 10
y := 3.4 // L.5
z := x + y
unused := 10
for i := 0; i; i++ {} // L.10
_, _ = a, z}
2:10: undeclared name: undefined 6:10: invalid operation: mismatched types int and float64 10:17: non-boolean condition in for statement 8:5: unused declared but not used