N2Wiki > Go言語学習帳
一覧 [非表示]
Go言語で写経してゆくページ。[Go]
☆環境構築↑
- Portable Ubuntu
- 8.04→8.10→9.04
- Goのインストール
☆HelloWorld↑
package main import "fmt" func main() { fmt.Printf("Hello, world!\n"); }
☆Ackermann↑
package main import "fmt" func main() { fmt.Printf("ack(3,9): %d \n",ack(3,9)); } func ack(m, n int) int { switch { case m == 0: return n+1; case n == 0: return ack(m-1, 1); } return ack(m-1, ack(m, n-1)); }
- default: return ack(m-1, ack(m, n-1)); と書くと「returnがない」と叱られる。
☆AccumulatorGenerator↑
package main import "fmt" func main() { f := accgen(10); a := f(1); b := f(2); fmt.Printf("a: %d, b: %d \n",a,b); } func accgen(n int) (func(int) int) { return func(x int) int { n += x; return n; }; }
- あとで気づいたけどtestのclosure.goの中にあった。
- return n += x; と書くと叱られます。
☆BankAccount↑
package main import "fmt" type BankAccountInterface interface { set(x float); get() float; } func deposit(b BankAccountInterface, x float) { b.set(b.get() + x); } func withdraw(b BankAccountInterface, x float) { dollars := b.get() - x; if dollars < 0 { dollars = 0; } b.set(dollars); } type bankAccount struct { dollars float; } func (b *bankAccount) set(x float) { b.dollars = x; } func (b *bankAccount) get() float { return b.dollars; } type stockAccount struct { numShares float; pricePerShare float; } func (b *stockAccount) get() float { return b.pricePerShare * b.numShares; } func (b *stockAccount) set(x float) { b.numShares = x / b.pricePerShare; } func p(v ...) { fmt.Println(v); } func main() { account := &bankAccount{200}; p(account.get()); deposit(account,50); p(account.get()); withdraw(account,100); p(account.get()); withdraw(account,200); p(account.get()); stock := &stockAccount{10, 30}; p(stock.numShares); p(stock.pricePerShare); p(stock.get()); stock.set(150); p(stock.numShares); stock.set(600); p(stock.get()); p(stock.numShares); deposit(stock,60); p(stock.get()); p(stock.numShares); }
- もっとGoらしい書き方というものがあるのかもしれない・・・
- クラスベースオブジェクト指向の考え方から頭を切り替えないとはまる。
- かといってプロトタイプベースでもない。
☆FluentInterface↑
package main import "fmt" type myType struct { i int; } type fluent interface { p() fluent; add(n int) fluent; } func (self *myType) p() fluent { fmt.Println(self.i); return self; } func (self *myType) add(n int) fluent { self.i += n; return self; } type fluent2 interface { fluent; sub(n int) fluent2; } func (self *myType) sub(n int) fluent2 { self.i -= n; return self; } func main() { x := &myType{10}; // x.sub(2).p().add(10).p().sub(3).p(); // error! x.sub(2).p().add(10).p().(fluent2).sub(3).p(); // type assertion }
- receiverにはInterfaceを書けない。
- 戻り値の型にはInterfaceが書ける。
- Interfaceは継承(?)できる。
- Interfaceに定義されていないメソッドを呼ぼうとするとコンパイルエラー
- Type Assertionするとコンパイルが通り実行時に型変換。
- Google先生、SelfTypeか型変数がほしいです・・・。
☆fix↑
package main import "fmt" type unaryFunc func (int) int; func fibMaker(f unaryFunc) unaryFunc { return func (x int) int { if x <= 1 { return 1 } return f(x-1) + f(x-2); }; } func fix(g func (unaryFunc) unaryFunc) unaryFunc { return g(func(x int) int { return fix(g)(x) }); } func main() { fib := fix(fibMaker); for i := 1; i < 6; i++ { fmt.Println(fib(i)); } }
☆decorator↑
package main import "fmt" type staff struct { payment float; } type employee interface { getOvertimePay() float; } func showOvertimePay(e employee, name string) { fmt.Printf("%s: I'm getting %f yen. Haha!\n", name, e.getOvertimePay() ); } func (self *staff) getOvertimePay() float { return self.payment; } type beTechnical struct { prototype employee; } func (self *beTechnical) getOvertimePay() float { return self.prototype.getOvertimePay() * 1.1; } type beLicensed struct { prototype employee; } func (self *beLicensed) getOvertimePay() float { return self.prototype.getOvertimePay() * 1.2; } type beManager struct { prototype employee; } func (self *beManager) getOvertimePay() float { return 0; } type beTemporary struct { prototype employee; } func (self *beTemporary) getOvertimePay() float { return 1000; } func main() { john := &beTechnical{&beLicensed{&staff{1000}}}; showOvertimePay(john, "John"); elen := &beTemporary{&beTechnical{&staff{1000}}}; showOvertimePay(elen, "Elen"); }
☆FizzBuzz↑
package main import "fmt" func natsGen() chan int { ch := make(chan int); go func() { for i := 1; ; i++ { ch <- i } }(); return ch; } func fizzGen() chan string { ch := make(chan string); go func() { for { ch <- ""; ch <- ""; ch <- "Fizz"; } }(); return ch; } func buzzGen() chan string { ch := make(chan string); go func() { for { ch <- ""; ch <- ""; ch <- ""; ch <- ""; ch <- "Buzz"; } }(); return ch; } func fizzBuzz() chan string { out := make(chan string); go func() { nats := natsGen(); fizz := fizzGen(); buzz := buzzGen(); for { n := <- nats; f := <- fizz; b := <- buzz; if f != "" || b != "" { out <- f + b; } else { out <- fmt.Sprintf("%d", n); } } }(); return out; } func main() { fizzbuzz := fizzBuzz(); for i := 1 ; i <= 30 ; i++ { fmt.Println(<-fizzbuzz); } }
☆Fibonacci↑
package main import "fmt" func fibonacci() chan int { ch := make(chan int); go func() { a := 0; b := 1; for { a, b = b, a+b; ch <- a; } }(); return ch; } func main() { fibs := fibonacci(); for i := 0 ; i < 34 ; i++ { fmt.Println(<-fibs); } }