第5章 関数¶
Luaに限らず,多くのプログラミング言語に欠かせない概念の一つとして関数というものが存在します. 実は今まで関数を何回も使っていました. 例えばprintですが,これは関数です.io.readも関数です. 関数とはいくつもの命令を集め1つの塊として定義したものです. 同じ処理を何回も行いたい場合は,関数を1つ定義して呼び出すだけでよいです.
関数の作り方¶
では,関数を作ってみましょう. 関数は次のように定義します.
書式
function 関数名( 引数 )
処理
end
ここで,二つの値を引数として渡し,その和を求める関数を作ってみましょう.
function sum(x, y)
return x + y
end
hoge = 10
piyo = 20
result = sum( hoge, piyo )
print( hoge .. " + " .. piyo .. " = " .. result )
実行結果
10 + 20 = 30
まずsum関数を使う前に,関数を定義しておかなければならない事に注意してください. 関数には好きな名前をつけてください.ただし,すでに使われている関数名や変数名は使わないでください. 例えば,printなどの名前をつけないでください. 関数命名のルールは変数の場合と同じです.
C言語との違い
プロトタイプ宣言は無い
さて,関数を呼び出す際に
sum( hoge, piyo )
としました. 関数を呼び出す際には引数と呼ばれるものを渡します. この引数とはどういったものでしょうか.
上図は引数の様子を示した図です. 呼び出した側の引数を実引数といい,呼び出された側の引数を仮引数といいます.
このとき,実引数の値が仮引数の値にコピーされます. つまり,
function func(x, y)
x = 10
y = 20
end
hoge = 12
piyo = 22
func( hoge, piyo )
print(hoge, piyo )
としても,x,y はhoge, piyoのコピーなので,中身をいくら書き換えても呼び出しもとのhoge, piyoには影響を及ぼしません.
引数に関して,もしかしたら何も受け取る必要が無い場合があるかもしれません. そういった場合は,引数の中は空にしておきます.
関数の戻り値に関しては次節で説明します.
関数の戻り値¶
関数には戻り値と呼ばれるものが存在しています. 前節のプログラムと下図を見てください.
returnは値を関数を呼び出した側に返す命令です. よって,x + y の計算結果を呼び出し元に返しています. つまり,変数resultには計算結果が代入されます.
Luaは複数の値を戻り値として返すことができます. 例えば,次のようなことができます.
function func()
return 10, 20
end
hoge, piyo = func()
print(hoge, piyo)
実行結果
10 20
hogeには10が,piyoには20が代入されます. では,次のようなコードを書いた場合どうなるでしょうか.
function func()
return 10, 20
end
hoge = func()
print(hoge, piyo)
この場合,第2の戻り値である20は使われず消滅します.
実行結果
10 nil
また,次のようなコードを書いた場合はどうでしょうか
function func()
return 10
end
piyo = 20
hoge, piyo = func()
print(hoge, piyo)
第2の戻り値はありません. この場合,piyoにはnilが代入されます. piyoは20ではないので注意してください.
実行結果
10 nil
何も返さない関数¶
戻り値の関数,つまり何も返さない関数を作ることもできます. その場合returnを書かなければ良いのです.
function func()
print("関数が呼び出されました")
end
func()
実行結果
関数が呼び出されました
また,明示的に戻り値が無いことを示すため,returnだけを書くこともできます.
function func()
print("関数が呼び出されました")
return
end
func()
上記の二つのコードは全く同じものです.
変数に関数を代入する¶
Luaの変数にはどんな値でも代入することができます. たとえ関数であろうとも代入が可能です.例えば次のようなことも可能です.
function sum(x, y)
return x + y
end
function mul(x, y)
return x * y
end
hoge = sum
print("hoge is " .. type(hoge) );
print("10 + 20 is " .. hoge(10, 20) )
hoge = mul
print("10 * 20 is " .. hoge(10, 20) )
type関数は現在の変数の型を調べるものでしたね. hogeにはsum関数やmul関数を代入しています. そして,hogeを使い関数にアクセスすることもできます. C言語をご存知の方は関数ポインタのようなことができると思ってください
実行結果
hoge is function
10 + 20 is 30
10 * 20 is 200
関数中に関数を定義する¶
Luaでは関数内に関数を定義することも可能です.
function func(x)
local function get()
return x
end
local function add(value)
x = x + value
end
return get, add
end
firstGetValue, firstAddValue = func(10)
secondGetValue, secondAddValue = func(30)
print("first value : " .. firstGetValue() )
print("second value : " .. secondGetValue() )
firstAddValue( 15 )
secondAddValue( 20 )
print("first value : " .. firstGetValue() )
print("second value : " .. secondGetValue() )
func関数はgetとadd関数を戻り値として返しています. ここでlocalという新しいキーワードが登場しました. このlocalについては有効範囲の章で詳しく説明します. 簡単に説明しておきますと,localというキーワードを付けることでローカル変数(またはローカル関数)を作成することができます. 要は,get関数もadd関数もfunc関数内からでしか呼び出せないということです.
実行結果
first value : 10
second value : 30
first value : 25
second value : 50
無名関数¶
名前無し関数を作成することも可能です. 例えば次のようなコードを書くことができます.
function createSquare()
return function(x)
return x*x
end
end
square = createSquare()
print("10 * 10 is " .. square(10, 10) )
reateSquare関数は戻り値にx*xを行う関数を返しています.
実行結果
10 * 10 is 100
基本ライブラリ¶
ここでは,基本ライブラリに用意されている関数の一部を紹介します.
assert関数¶
定義
assert (v [, message])
- assert関数はvが偽条件ならばエラーを発生させる関数です.
- messageにはエラーメッセージを渡します. エラーメッセージは省略可能です.
hoge = true
assert( hoge, "Error #1")
hoge = false
assert( hoge, "Error #2")
実行結果
lua51m.exe: test.lua:4: Error #2
stack traceback:
[C]: in function 'assert'
test.lua:4: in main chunk
[C]: ?
dofile関数¶
定義
dofile( filename)
dofile関数はfilenameで指定したファイルを実行する関数です. 例えば以下のようにして使います. 今回は二つのLuaファイル,test.luaとcall.luaにコードを記述しています.
-- call.lua
function testFunc()
print ("Hello")
return "World!"
end
-- test.lua
dofile("call.lua")
hoge = testFunc()
print( hoge )
実行結果
Hello
World!
dofileでcall.luaを読み込む事により,test.lua側で testFunc関数を利用することができます.
type関数¶
定義
type (v)
type関数は,データの型を返す関数です.
hoge = nil
print("hoge : " .. type(hoge))
hoge = 10
print("hoge : " .. type(hoge))
hoge = true
print("hoge : " .. type(hoge))
hoge = "Hello"
print("hoge : " .. type(hoge))
実行結果
hoge : nil
hoge : number
hoge : boolean
tonumber関数¶
定義
tonumber (e [, base])
tonumber関数は引数eを数値に変換する関数です. 数値変換が可能な場合は数値を返し,そうでなければnilを返します.
また,baseを指定すると,eをbase進法の数値として変換します. 省略すると,10が自動的に指定されます.
hoge = "25"
print("hoge :" .. hoge .. " type :" .. type( hoge ) )
piyo = tonumber( hoge )
print("piyo :" .. piyo .. " type :" .. type(piyo) )
実行結果
hoge :25 type :string
piyo :25 type :number
tostring関数¶
定義
tostring ( e )
tostring関数はeを文字列に変換する関数です.
hoge = 25
print("hoge :" .. hoge .. " type :" .. type( hoge ) )
piyo = tostring( hoge )
print("piyo :" .. piyo .. " type :" .. type(piyo) )
実行結果
hoge :25 type :number
piyo :25 type :string
数値から文字列に変換する際は,わざわざtostring関数を使用しなくても,空の文字列を追加するだけでよいです.
piyo = hoge .. ""