こんにちは、エンジニアの東です。
PHPerが学ぶgo tour #1 ~基本~に引き続き、
PHPerがTour of Goで学んでいくときのためにPHPとGoでの書き方の比較をしていきたいと思います。
制御構文
今回はTour of Goの制御構文から(https://go-tour-jp.appspot.com/flowcontrol/1)紹介していきます。
制御構文は制御文に括弧がいらなくて戸惑うかと思いいますが、それくらいであとは基本的にシンプルです。
for
いわゆる普通のfor文です。foreach文についてはまた別記事で紹介していきます。
go package main import "fmt" func main() { sum := 0 for i := 0; i < 10; i++ { sum += i } fmt.Println(sum) }
(引用: https://go-tour-jp.appspot.com/flowcontrol/1)
php namespace Main; class Main { static function main() { $sum = 0; for ($i = 0; $i < 10; $i++) { $sum += $i; } print($sum."\n"); } } Main::main();
GoにおけるWhile
go package main import "fmt" func main() { sum := 1 for sum < 1000 { sum += sum } fmt.Println(sum) }
(引用: https://go-tour-jp.appspot.com/flowcontrol/3)
php namespace Main; class Main { static function main() { $sum = 1; while ($sum < 1000) { $sum++; } print($sum."\n"); } } Main::main();
if
go package main import ( "fmt" "math" ) func sqrt(x float64) string { if x < 0 { return sqrt(-x) + "i" } return fmt.Sprint(math.Sqrt(x)) } func main() { fmt.Println(sqrt(2), sqrt(-4)) }
(引用: https://go-tour-jp.appspot.com/flowcontrol/5)
php namespace Main; class Main { protected function sqrt(float $x) : string { if ($x < 0) { return sprintf("%f%s", sqrt(-$x), 'i'); } return sprintf("%f", sqrt($x)); } static function main() { print(self::sqrt(2).' '.self::sqrt(-4)."\n"); } } Main::main();
If with a short statement
go package main import ( "fmt" "math" ) func pow(x, n, lim float64) float64 { if v := math.Pow(x, n); v < lim { return v } return lim } func main() { fmt.Println( pow(3, 2, 10), pow(3, 3, 20), ) }
(引用: https://go-tour-jp.appspot.com/flowcontrol/6)
php namespace Main; class Main { protected function pow(int $x, int $n, float $lim) : float { $v = pow($x, $n); if ($v < $lim) { return $v; } else { printf("%f >= %f \n", $v, $lim); } unset($v); return $lim; } static function main() { print(self::pow(3, 2, 10)."\n"); print(self::pow(3, 3, 20)."\n"); } } Main::main();
if else
評価文のための簡単なステートメントを評価文に記述でき、
if文のためだけの変数をいつまでも保持しつづけなくて済みます。
go package main import ( "fmt" "math" ) func pow(x, n, lim float64) float64 { if v := math.Pow(x, n); v < lim { return v } else { fmt.Printf("%g >= %g\n", v, lim) } // can't use v here, though return lim } func main() { fmt.Println( pow(3, 2, 10), pow(3, 3, 20), ) }
(引用: https://go-tour-jp.appspot.com/flowcontrol/7)
php namespace Main; class Main { protected function pow(int $x, int $n, float $lim) : float { $v = pow($x, $n); if ($v < $lim) { return $v; } else { printf("%f >= %f \n", $v, $lim); } unset($v); return $lim; } static function main() { print(self::pow(3, 2, 10)."\n"); print(self::pow(3, 3, 20)."\n"); } } Main::main();
switch
switchはGo言語はBreakとかかなくてもBreakされるエコな書き方です!
Breakしてほしくない場合だけ、fallthroughと書いてあげればよいのです。
go package main import ( "fmt" "runtime" ) func main() { fmt.Print("Go runs on ") switch os := runtime.GOOS; os { case "darwin": fmt.Println("OS X.") case "linux": fmt.Println("Linux.") default: // freebsd, openbsd, // plan9, windows... fmt.Printf("%s.", os) } }
(引用: https://go-tour-jp.appspot.com/flowcontrol/9)
php print('Go runs on '); $os = 'linux'; switch ($os) { case 'darwin': print('OS X.'); break; case 'linux': print('Linux.'); break; default: printf("%s.", $os); }
defer
Goの非常に便利なのがDeferです。
「ファイルオープンしたので、後でクローズしてねー」
と、予約するように記述ができるのと、スタック(Last-In First-Out)で実行されるため、入れ子でオープンクローズしている場合も安心です。
go package main import "fmt" func main() { defer fmt.Println("world") fmt.Println("hello") }
(引用: https://go-tour-jp.appspot.com/flowcontrol/12)
php try { print("hello "); } finally { print("world"); }
これくらい簡単なものだとありがたみがわかりづらいですが、関数でネストしていったり、行数が多くなってクローズするの忘れてた!っていうのが防げます。
後ですることを宣言することのありがたみは複雑なシステムになればなるほど実感するのかもしれません!
いかがだったでしょうか!
今回はGoの制御構文についてPHPを絡めて紹介しました。
次回はポインタを紹介したいと思います。