関数という名の (定|変) 数
連載第1回目
- 変数に代入できる
- 関数の引数にできる
- 関数を返す関数が書ける
JavaScript,
リスト1 FizzBuzzの例
var fizzbuzz = function(n) {
if (n % 15 == 0) { return "FizzBuzz"; }
if (n % 5 == 0) { return "Buzz"; }
if (n % 3 == 0) { return "Fizz"; }
return n;
}
for (var i = 1; i <= 100; i++) {
console.log(fizzbuzz(i))
}
見てのとおり,fizzbuzz
は変数名で,
var fizzubzz = func(n:Int)->String {
if n % 15 == 0 { return "FizzBuzz" }
if n % 5 == 0 { return "Buzz" }
if n % 3 == 0 { return "Fizz" }
return String(n)
}
いいえ,
var fizzbuzz = { (n:Int)->String in
if n % 15 == 0 { return "FizzBuzz" }
if n % 5 == 0 { return "Buzz" }
if n % 3 == 0 { return "Fizz" }
return String(n)
}
あるいはこうです。
var fizzbuzz:(Int)->String = { n in
if n % 15 == 0 { return "FizzBuzz" }
if n % 5 == 0 { return "Buzz" }
if n % 3 == 0 { return "Fizz" }
return String(n)
}
まとめるとこう。
- funcは不要
- →
{ 引数 in 定義 }
という形をしている
- →
- 型指定は必要
- →前者は
{型定義付き引数 in 定義}
- →後者は
変数名:型 = { 引数名 in 定義 }
- →前者は
変数指定を{}
の外ではなく中でやるあたり,
リスト2 JavaScriptの場合
function range(start, end) { // ないので作る
var ret = [];
for (var i = start; i <= end; i++) ret.push(i);
return ret;
}
var a = range(1, 100).map(fizzbuzz)
console.log(a)
ここで,fizzbuzz()
を無名化するとこうなります。
var a = range(1, 100).map(function(n) {
if (n % 15 == 0) { return "FizzBuzz"; }
if (n % 5 == 0) { return "Buzz"; }
if (n % 3 == 0) { return "Fizz"; }
return n;
}))
動くことは動きますが,()
の中に入ったfunction
はなんとも不格好です。Rubyならどうでしょうか?
a = (1..100).map { ¦n¦
if n % 15 == 0 then "FizzBuzz"
elsif n % 5 == 0 then "Buzz"
elsif n % 3 == 0 then "Fizz"
else n.to_s
end
}
p a
「メソッドの最後の引数がブロックの場合,
var a = (1...100).map { n in
if n % 15 == 0 { return "FizzBuzz" }
if n % 5 == 0 { return "Buzz" }
if n % 3 == 0 { return "Fizz" }
return String(n)
}
println(a)
見てのとおり,map
の後の無名関数を()
でくくらなくても動きました。無名関数の引数と戻り値のほうも指定していません。このあたりは,
しかし,
リスト3 Rubyのアイデアを拝借
var a = (1...100).map {
if $0 % 15 == 0 { return "FizzBuzz" }
if $0 % 5 == 0 { return "Buzz" }
if $0 % 3 == 0 { return "Fizz" }
return String($0)
}
println(a)
なんと,in
が消えてしまいました。その代わりn
があった位置に$0
という未宣言の変数が存在します。この変数のことをプレイスホルダー$0
が最初の引数,$1
が次の引数といった具合です。これ,