More Related Content Similar to Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏) (20) Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)6. What's new?
DevFest (2010/3)から
complex型
x := m[k] がpanicしなくなった。
s[0:n] が s[:n]に
panic(), recover()
goinstallコマンド
gomakeコマンド ($GOOS, $GOARCH, ...)
goprofコマンド
Go dashboard
new package
crypto/ripemd160, hash/crc64, crypto/rand, utf16, nntp, mime/multipart, html, net/textp
roto, net/dict, crypto/ocsp, runtime/pprof, http/pprof, cmath, rpc/jsonrpc,
go/typechecker
once -> sync.Once()
11. 入力: bufio
http://golang.org/pkg/bufio/#Reader.ReadBytes
func (*Reader) ReadBytes
func (b *Reader) ReadBytes(delim byte) (line []byte, err os.Error)
ReadBytes reads until the first occurrence of delim in the input, returning a string containing the data up to and
including the delimiter. If ReadBytes encounters an error before finding a delimiter, it returns the data read
before the error and the error itself (often os.EOF). ReadBytes returns err != nil if and only if line does not end in
delim.
import ("bufio"; "os")
in := bufio.NewReader(os.Stdin)
line, err := in.ReadBytes('n')
if err != nil { ... }
12. 出力: fmt
http://golang.org/pkg/fmt/#Printf
func Printf
func Printf(format string, a ...interface{}) (n int, errno os.Error)
Printf formats according to a format specifier and writes to standard output. It returns the number of bytes written and
any write error encountered.
import "fmt"
fmt.Printf("> ")
fmt.Printf("%d", i)
fmt.Printf("%#v", v)
13. コンパイル&実行
% cat main.go
package main
import ("bufio"; "fmt"; "os")
func main() {
in := bufio.NewReader(os.Stdin)
for {
line, err := in.ReadBytes('n')
if err != nil { break }
fmt.Println(string(line))
}
}
% 6g main.go # 8g main.go
% 6l main.6 # 8l main.8
% ./6.out # ./8.out
14. Read-eval-print loop
package main
import ("bufio"; "fmt"; "os")
func readEvalPrint(in *bufio.Reader, env *Env) os.Error
func main() {
in := bufio.NewReader(os.Stdin)
env := NewEnv() // for variable table
for {
err := readEvalPrint(in, env)
if err != nil { break }
}
}
15. Read-eval-print loop
func readEvalPrint(in *bufio.Reader, env *Env) os.Error {
fmt.Printf("> ")
line, err := in.ReadBytes('n')
if err != nil { return err }
ast, nbuf := Read(line)
v := Eval(ast, env)
fmt.Println(Print(v, env))
return nil
}
16. Read: getNum
func getNum(buf []byte) (n int, nbuf []byte) {
n := digitVal(buf[0])
nbuf = buf[1:]
for len(nbuf) > 0 {
if d := digitVal(nbuf[0]); d >= 0 {
n = n * 10 + d
} else { break }
nbuf = nbuf[1:]
}
return n, nbuf
}
func digitVal(b byte) int {
if b >= '0' && b <= '9' {
return int(b - '0') // int型に変換
} else { return -1 }
}
18. Read: getSymbol
func getSymbol(buf []byte) (sym string, nbuf []byte) {
var i int
for i = 0; i < len(buf); i++ {
if !isAlpha(buf[i]) && !isDigit(buf[i]) {
break
}
}
return string(buf[0:i]), buf[i:]
}
20. 再帰降下パーザ
// stmt := expr | sym '=' expr
func parseStatement(b []byte) (stmt Ast, n []byte)
// expr := ['+'|'-'] term { ['+'|'-'] term }
func parseExpression(b []byte) (expr Ast, n []byte)
// term := factor { ['*'|'/'] factor }
func parseTerm(b []byte) (term Ast, n []byte)
// factor := num | symbol | '(' expr ')'
func parseFactor(b []byte) (factor Ast, n []byte)
21. interface: Ast
type Ast interface {
String() string
Eval(env* Env) Ast
}
Ast型の変数に代入できるのは、これらのメソッドが定義されて
いる型のオブジェクト
Astにいれて使う型はこれらのメソッドを定義
Astを使うほうは、これらのメソッドが利用可能
22. named type: Num
type Num int
func (n Num) String() string {
return fmt.Sprintf("%d", int(n))
}
func (n Num) Eval(env *Env) Ast { return n }
func getNum(b []byte) (num Num, nbuf []byte) {
...
return Num(n), nbuf
}
NumはAst型
23. named type: Symbol
type Symbol string
func (s Symbol) String() string {
return string(s)
}
func (s Symbol) Eval(env *Env) Ast { ... }
SymbolもAst型
24. map: variable table
type Env struct { Var map[string]Ast; .. }
func NewEnv() *Env {
env := new(Env)
env.Var = make(map[string]Ast)
return env
}
func Set(env* Env, key string, n int) {
env.Var[key] = Num(n)
}
func envValue(env* Env, key string) (n int, ok bool) {
if v, found := env.Var[key]; found {
..
}
return 0, false
}
26. BinOp
type Ast interface { .. }
type BinOp struct { Op byte; Left, Right Ast }
func (b BinOp) String() string {..}
func (b BinOp) Eval(env *Env) Ast { .. }
func parseExpression(b []byte) (expr Ast, n []byte) {
expr, n = parseTerm(b)
for n[0] == '+' || n[0] == '-' {
op := n[0]; var term Ast
term, n = parseTerm(n[1:])
expr = BinOp{Op: op, Left:expr, Right:term}
}
return expr, n
}
BinOpもAst型
28. interface type-switch
func parseStatement(b []byte) (stmt Ast, n []byte) {
stmt, n = parseExpression(b)
if n[0] == '=' {
if sym, ok := stmt.(Symbol); ok {
var expr Ast
expr, n = parseExpression(n[1:])
stmt = AssignOp{Var:sym, Expr:expr}
} else { /* 例外処理 */ }
}
return stmt, n
}
29. 例外処理
func readEvalPrint(in *bufio.Reader, env *Env) os.Error {
defer func() { if x := recover(); x != nil { ... } }()
.. Read(line) ..
}
func Read(b []byte) (ast Ast, n[]byte) {
return parseStatement(b)
}
func parseStatement(b []byte) (stmt Ast, n []byte) {
...
if sym, ok := stmt.(Symbol); ok { ..
} else {
panic("lvalue is not symbol:" + stmt.String());
}
}
33. packageディレクトリ
% mkdir godentaku; mv godentaku.* godentaku/; cd godentaku
% cat > Makefile
include $(GOROOT)/src/Make.inc
TARG=godentaku # importでつかうパッケージパス
GOFILES=
godentaku.go
include $(GOROOT)/src/Make.pkg
% gomake # コンパイルとリンク
% gomake install # -> ${GOROOT}/pkg/${GOOS}_${GOARCH}/${TARG}.a
39. hgrc
% cat .hg/hgrc
[paths]
default = https://yourproj.googlecode.com/hg/
[ui]
username = Your Name <foo@example.com>
[auth]
googlecode.prefix = yourproj.googlecode.com/hg/
gogolecode.username = foo@example.com
googlecode.password = XXXXX
googlecode.schemes = https