こんにちは、エンジニアの東です。
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を絡めて紹介しました。
次回はポインタを紹介したいと思います。