【概要】
この記事では A Tour of Go のExercise: Fibonacci closure の解答例をgolangおよびPHPで提示します。phperの方はこの解答例を参考にしてGopherちゃんと触れ合っていただけると幸いです。
今回取り扱うExerciseの内容は下記の通りです
関数を用いた面白い例を見てみましょう。
fibonacci (フィボナッチ)関数を実装しましょう。この関数は、連続するフィボナッチ数(0, 1, 1, 2, 3, 5, ...)を返す関数(クロージャ)を返します。
【golangでの解答例】
- コード
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
a := 0
b := 1
return func() int {
a, b = b, a+b
return a
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
- 実行結果
1
1
2
3
5
8
13
21
34
55
【PHPでの解答例】
- コード
<?php
$fibonacci = function ()
{
return function() {
static $a = 0;
static $b = 1;
$tmp = $b;
$b = $a + $b;
$a = $tmp;
return $a;
};
};
$func = $fibonacci();
for ($i = 0; $i < 10; $i++) {
echo $func() . "\n";
}
- 実行結果
1
1
2
3
5
8
13
21
34
55
ちなみに2回目以降もちゃんと動きます
<?php
$fibonacci = function ()
{
return function() {
static $a = 0;
static $b = 1;
$tmp = $b;
$b = $a + $b;
$a = $tmp;
return $a;
};
};
echo "--- func result ---\n";
$func = $fibonacci();
for ($i = 0; $i < 10; $i++) {
echo $func() . "\n";
}
echo "--- func2 result ---\n";
$func2 = $fibonacci();
for ($i = 0; $i < 10; $i++) {
echo $func2() . "\n";
}
--- func result ---
1
1
2
3
5
8
13
21
34
55
--- func2 result ---
1
1
2
3
5
8
13
21
34
55
【golangとPHPを比較して】
PHP7.2から戻り値の型を定義できるようにはなりましたが、定義できる型はクラス名/インターフェース名, self, array, callable, bool, float, int, string, iterableのみであるためクロージャーを戻り値の型として定義することができません。
一方でgolangは下記のように戻り値の型としてクロージャーを定義することができ、更にはクロージャーの戻り値の型まで定義することができます。
func fibonacci() func() int {
PHPにも導入されませんかね???