こんにちは、エンジニアの東です。

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を絡めて紹介しました。
次回はポインタを紹介したいと思います。

Join Us !

ウエディングパークでは、一緒に働く仲間を募集しています!
ご興味ある方は、お気軽にお問合せください(カジュアル面談から可)

採用情報を見る