2011年7月2日土曜日

▲ 今日からはじめる Google The Go programming language

【はじめに】
・ここに掲載してあります、「BLOG投稿」の内容は主に概要を記載してあります。
・詳細な、「導入・構築・操作マニュアル」等は本文中に記載してあります、
>(例)・click -> ■マニュアルのタイトル のような別リンクを張っています。
・このリンクは、■Google ドキュメント で記載されたもので、
>「共有設定」-> ◎「ウエッブで一般公開」されています。
●また、画像はクリックすると拡大表示できます。

【Windows版 32bit 対応】
(1)まず、Linux環境に導入する前にWindows環境でGO言語を試して、
その後Ubuntu 11.04 Linux 環境を構築し導入する試行手順を紹介いたします。

click(PowerPoint:詳細手順操作マニュアル) -> ■ Windows Porting –GOを試行してみる。 Install->Compile->Run 迄を実行

【Windows Porting –GO 導入フロー】
【Go言語:ソースコード】作成例
【Go言語:Compile & Run】実行例
【Go言語:Command】


【Ubuntu Linux版 32bit 対応】
■The Go programming languageの導入

【The Go programming languageの特徴】
・Goプログラミング言語の文法は、型宣言を除いてC言語と似ている。
・for文やif文について、括弧 () で括らない
・メモリ管理はガベージコレクションに一任され、連想配列も備える。
・並列処理はアントニー・ホーアによるCSPのプロセス代数をモデルとする。
 また、チャンネル といったPi-calculusの特徴も持つ。
・例外処理やクラスの継承、ジェネリックプログラミング、アサーション、
 オーバーロードといった機能が存在しない。
・関数は多値を返すことができる。

【Introduction:The Go programming language】
□The Go programming language (open source コンパイル型の言語) Introduction Links □Quick Links □For newcomers:   http://golang.org/doc/install.html ■Getting Started   http://golang.org/doc/go_tutorial.html ■Tutorial   http://golang.org/doc/effective_go.html ■Effective Go http://golang.org/doc/go_faq.html ■Go FAQ http://golang.org/doc/docs.html ■Other Documentation http://code.google.com/intl/ja/appengine/docs/go/ ■Go for Google App Engine □For developers: http://godashboard.appspot.com/package ■Package Dashboard http://code.google.com/p/go/issues/list ■Issue Tracker http://godashboard.appspot.com/ ■Build Status http://code.google.com/p/go/source/browse/ ■Go Source http://code.google.com/p/go/source/list ■[changes] http://golang.org/pkg/ ■Package Reference http://golang.org/doc/go_spec.html ■Language Specification □Go Videos  http://www.youtube.com/watch?v=-i0hat7pdpk ■Google I/O 2011: Writing Web Apps in Go □Go Blog  http://blog.golang.org/2011/06/profiling-go-programs.html  ■Profiling Go ProgramsFri, 24 Jun http://blog.golang.org/2011/06/spotlight-on-external-go-libraries.html  ■Spotlight on external Go librariesFri, 03 Jun  http://blog.golang.org/2011/05/gif-decoder-exercise-in-go-interfaces.html  ■A GIF decoder: an exercise in Go interfacesWed, 25 May 【step_01:Getting Started】 
click -> (注):「2011年7月2日土曜日:▲ 今日からはじめる 
 Ubuntu 11.04 (Natty Narwhal) の Install 操作ガイド」で構築した
 Ubuntu 11.04「Google The Go programming language」を導入します。
 
click -> (PowrPoint) ■The Go programming language 導入操作マニュアル:Getting Started ■A Tutorial for the Go Programming Language 【Day 1】The Go Programming Language Part 1 【Day 2】The Go Programming Language Part 2 【Day 3】The Go Programming Language Part 3 【Videos and Talks】 ■Writing Web Apps in Go ・presentation slides ■Real World Go ・presentation slides ■Go Programming ■Practical Go Programming ・presentation slides ■The Go Tech Talk ・presentation slides ■gocoding YouTube Channel ■Screencast: Writing Go Packages ■Screencast: Testing Go Packages (slide)■The Expressiveness Of Go ■Another Go at Language Design ・presentation slides ■Go Emerging Languages Conference Talk ・presentation slides (pdf)■The Go frontend for GCC ■The Go Promo Video ◆◆◆ Samples ◆◆◆ ◆【01_Hello World!】 package main import "fmt" func main() { fmt.Println("Hello, 世界") } 【01_Compile & Run】 Hello, 世界 ◆【02_Fibonacci Closure】 package main // fib returns a function that returns // successive Fibonacci numbers. func fib() func() int { a, b := 0, 1 return func() int { a, b = b, a+b return b } } func main() { f := fib() // Function calls are evaluated left-to-right. println(f(), f(), f(), f(), f()) } 【02_Compile & Run】 1 2 3 5 8 ◆【03_Peano Integers】 // Peano integers are represented by a linked list // whose nodes contain no data (the nodes are the data). // See: http://en.wikipedia.org/wiki/Peano_axioms // This program demonstrates the power of Go's // segmented stacks when doing massively recursive // computations. package main import "fmt" // Number is a pointer to a Number type Number *Number // The arithmetic value of a Number is the count of // the nodes comprising the list. // (See the count function below.) // ------------------------------------- // Peano primitives func zero() *Number { return nil } func isZero(x *Number) bool { return x == nil } func add1(x *Number) *Number { e := new(Number) *e = x return e } func sub1(x *Number) *Number { return *x } func add(x, y *Number) *Number { if isZero(y) { return x } return add(add1(x), sub1(y)) } func mul(x, y *Number) *Number { if isZero(x) || isZero(y) { return zero() } return add(mul(x, sub1(y)), x) } func fact(n *Number) *Number { if isZero(n) { return add1(zero()) } return mul(fact(sub1(n)), n) } // ------------------------------------- // Helpers to generate/count Peano integers func gen(n int) *Number { if n > 0 { return add1(gen(n - 1)) } return zero() } func count(x *Number) int { if isZero(x) { return 0 } return count(sub1(x)) + 1 } // ------------------------------------- // Print i! for i in [0,9] func main() { for i := 0; i <= 9; i++ { f := count(fact(gen(i))) fmt.Println(i, "! =", f) } } 【03_Compile & Run】 0 ! = 1 1 ! = 1 2 ! = 2 3 ! = 6 4 ! = 24 5 ! = 120 6 ! = 720 7 ! = 5040 8 ! = 40320 9 ! = 362880 ◆【04_Concurrent pi】 // Concurrent computation of pi. // See http://goo.gl/ZuTZM. // // This demonstrates Go's ability to handle // large numbers of concurrent processes. // It is an unreasonable way to calculate pi. package main import ( "fmt" "math" ) func main() { fmt.Println(pi(5000)) } // pi launches n goroutines to compute an // approximation of pi. func pi(n int) float64 { ch := make(chan float64) for k := 0; k <= n; k++ { go term(ch, float64(k)) } f := 0.0 for k := 0; k <= n; k++ { f += <-ch } return f } func term(ch chan float64, k float64) { ch <- 4 * math.Pow(-1, k) / (2*k + 1) } 【04_Compile & Run】 3.1417926135957908 ◆【05_concurrent Prime Sieve】 // A concurrent prime sieve // See "Prime Numbers" section of the tutorial: // http://golang.org/doc/go_tutorial.html package main // Send the sequence 2, 3, 4, ... to channel 'ch'. func Generate(ch chan<- int) { for i := 2; ; i++ { ch <- i // Send 'i' to channel 'ch'. } } // Copy the values from channel 'in' to channel 'out', // removing those divisible by 'prime'. func Filter(in <-chan int, out chan<- int, prime int) { for { i := <-in // Receive value from 'in'. if i%prime != 0 { out <- i // Send 'i' to 'out'. } } } // The prime sieve: Daisy-chain Filter processes. func main() { ch := make(chan int) // Create a new channel. go Generate(ch) // Launch Generate goroutine. for i := 0; i < 10; i++ { prime := <-ch print(prime, "\n") ch1 := make(chan int) go Filter(ch, ch1, prime) ch = ch1 } } 【05_Compile & Run】 2 3 5 7 11 13 17 19 23 29 ◆【06_peg Solitaire Solver】 // This program solves the (English) peg solitaire // board game. See also: // http://en.wikipedia.org/wiki/Peg_solitaire package main import "fmt" const N = 11 + 1 // length of a board row (+1 for \n) // The board must be surrounded by 2 illegal fields // in each direction so that move() doesn't need to // check the board boundaries. Periods represent // illegal fields, ● are pegs, and ○ are holes. var board = []int( `........... ........... ....●●●.... ....●●●.... ..●●●●●●●.. ..●●●○●●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... `) // center is the position of the center hole if // there is a single one; otherwise it is -1. var center int func init() { n := 0 for pos, field := range board { if field == '○' { center = pos n++ } } if n != 1 { center = -1 // no single hole } } var moves int // number of times move is called // move tests if there is a peg at position pos that // can jump over another peg in direction dir. If the // move is valid, it is executed and move returns true. // Otherwise, move returns false. func move(pos, dir int) bool { moves++ if board[pos] == '●' && board[pos+dir] == '●' && board[pos+2*dir] == '○' { board[pos] = '○' board[pos+dir] = '○' board[pos+2*dir] = '●' return true } return false } // unmove reverts a previously executed valid move. func unmove(pos, dir int) { board[pos] = '●' board[pos+dir] = '●' board[pos+2*dir] = '○' } // solve tries to find a sequence of moves such that // there is only one peg left at the end; if center is // >= 0, that last peg must be in the center position. // If a solution is found, solve prints the board after // each move in a backward fashion (i.e., the last // board position is printed first, all the way back to // the starting board position). func solve() bool { var last, n int for pos, field := range board { // try each board position if field == '●' { // found a peg for _, dir := range [...]int{-1, -N, +1, +N} { // try each direction if move(pos, dir) { // a valid move was found and executed, // see if this new board has a solution if solve() { unmove(pos, dir) println(string(board)) return true } unmove(pos, dir) } } last = pos n++ } } // tried each possible move if n == 1 && (center < 0 || last == center) { // there's only one peg left println(string(board)) return true } // no solution found for this board return false } func main() { if !solve() { fmt.Println("no solution found") } fmt.Println(moves, "moves tried") } 【06_Compile & Run】 ........... ........... ....○○○.... ....○○○.... ..○○○○○○○.. ..○○○●○○○.. ..○○○○○○○.. ....○○○.... ....○○○.... ........... ........... ........... ........... ....○○○.... ....○○○.... ..○○○○○○○.. ..○○○○○○○.. ..○○○●○○○.. ....○●○.... ....○○○.... ........... ........... ........... ........... ....○○○.... ....○○○.... ..○○○○○○○.. ..○○○○○○○.. ..○○○○●●○.. ....○●○.... ....○○○.... ........... ........... ........... ........... ....○○○.... ....○○○.... ..○○○○●○○.. ..○○○○●○○.. ..○○○○○●○.. ....○●○.... ....○○○.... ........... ........... ........... ........... ....○○○.... ....○○○.... ..○○○○●○○.. ..○○○○●○○.. ..○○○●●○○.. ....○●○.... ....○○○.... ........... ........... ........... ........... ....○○○.... ....○○○.... ..○○○○●○○.. ..○○○○●○○.. ..○●●○●○○.. ....○●○.... ....○○○.... ........... ........... ........... ........... ....○○○.... ....○○○.... ..○○○○●○○.. ..○○○○●○○.. ..○●○○●○○.. ....●●○.... ....●○○.... ........... ........... ........... ........... ....○○○.... ....○○○.... ..○○○○●○○.. ..○○○○●○○.. ..○●○○●○○.. ....●●○.... ....○●●.... ........... ........... ........... ........... ....○○○.... ....○○○.... ..○○○○●○○.. ..○○●○●○○.. ..○●●○●○○.. ....○●○.... ....○●●.... ........... ........... ........... ........... ....○○○.... ....○○○.... ..○○○○●○○.. ..○○●○●○○.. ..○●○○●○○.. ....●●○.... ....●●●.... ........... ........... ........... ........... ....○○○.... ....○○○.... ..○○○○●○○.. ..○○●○●○○.. ..○●○○○●●.. ....●●○.... ....●●●.... ........... ........... ........... ........... ....○○○.... ....○○○.... ..○○○○●○○.. ..○○●○○○○.. ..○●○○●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....○○○.... ....○○○.... ..○○○○●○○.. ..○○●○○○○.. ..○○●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....○○○.... ....○○○.... ..○○○○●○○.. ..○○●○○○○.. ..●●○●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....○○○.... ....●○○.... ..○○●○●○○.. ..○○○○○○○.. ..●●○●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....○○○.... ....●○○.... ..○○○○●○○.. ..○○●○○○○.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....○○●.... ....●○●.... ..○○○○○○○.. ..○○●○○○○.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....○○●.... ....●○○.... ..○○○○●○○.. ..○○●○●○○.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....○○●.... ....●○○.... ..○○○○●○○.. ..○○●○○●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....○○●.... ....●○○.... ..○○○○●○○.. ..○○○●●●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....○○●.... ....○○○.... ..○○●○●○○.. ..○○●●●●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....○○●.... ....○○○.... ..○○●○●○○.. ..●●○●●●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....●○●.... ....●○○.... ..○○○○●○○.. ..●●○●●●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....●○●.... ....○○○.... ..○○●○●○○.. ..●●●●●●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....●○●.... ....○○○.... ..○○●○○●●.. ..●●●●●●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....●○○.... ....○○●.... ..○○●○●●●.. ..●●●●●●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....●○○.... ....○○●.... ..●●○○●●●.. ..●●●●●●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....●○○.... ....○○●.... ..●○●●●●●.. ..●●●●●●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....○●●.... ....○○●.... ..●○●●●●●.. ..●●●●●●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....●●●.... ....●○●.... ..●○○●●●●.. ..●●●●●●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....●●●.... ....●○●.... ..●●●○●●●.. ..●●●●●●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... ........... ........... ....●●●.... ....●●●.... ..●●●●●●●.. ..●●●○●●●.. ..●●●●●●●.. ....●●●.... ....●●●.... ........... ........... 391865 moves tried ◆【07_Tree Comparison】 // Two binary trees may be of different shapes, // but have the same contents. For example: // // 4 6 // 2 6 4 7 // 1 3 5 7 2 5 // 1 3 // // Go's concurrency primitives make it easy to // traverse and compare the contents of two trees // in parallel. package main import ( "fmt" "rand" ) // A Tree is a binary tree with integer values. type Tree struct { Left *Tree Value int Right *Tree } // Walk traverses a tree depth-first, // sending each Value on a channel. func Walk(t *Tree, ch chan int) { if t == nil { return } Walk(t.Left, ch) ch <- t.Value Walk(t.Right, ch) } // Walker launches Walk in a new goroutine, // and returns a read-only channel of values. func Walker(t *Tree) <-chan int { ch := make(chan int) go func() { Walk(t, ch) close(ch) }() return ch } // Compare reads values from two Walkers // that run simultaneously, and returns true // if t1 and t2 have the same contents. func Compare(t1, t2 *Tree) bool { c1, c2 := Walker(t1), Walker(t2) for { v1, ok1 := <-c1 v2, ok2 := <-c2 if !ok1 || !ok2 { return ok1 == ok2 } if v1 != v2 { break } } return false } // New returns a new, random binary tree // holding the values 1k, 2k, ..., nk. func New(n, k int) *Tree { var t *Tree for _, v := range rand.Perm(n) { t = insert(t, (1+v)*k) } return t } func insert(t *Tree, v int) *Tree { if t == nil { return &Tree{nil, v, nil} } if v < t.Value { t.Left = insert(t.Left, v) return t } t.Right = insert(t.Right, v) return t } func main() { t1 := New(100, 1) fmt.Println(Compare(t1, New(100, 1)), "Same Contents") fmt.Println(Compare(t1, New(99, 1)), "Differing Sizes") fmt.Println(Compare(t1, New(100, 2)), "Differing Values") fmt.Println(Compare(t1, New(101, 2)), "Dissimilar") } 【07_Compile & Run】 true Same Contents false Differing Sizes false Differing Values false Dissimilar