web-dev-qa-db-ja.com

関数の引数のデフォルト値を定義する

Lua wikiで、欠落している引数のデフォルト値を定義する方法を見つけました。

_function myfunction(a,b,c)
    b = b or 7
    c = c or 5
    print (a,b,c)
end
_

それが唯一の方法ですか? PHP style myfunction (a,b=7,c=5)は機能しないようです。Luaの方法が機能しないということではなく、これがそれを行う唯一の方法かどうか疑問に思っています。

80
ripat

PHPまたはPythonなどの名前付き引数とデフォルト値が必要な場合は、テーブルコンストラクターで関数を呼び出すことができます。

myfunction{a,b=3,c=2}

(これは LuaSocketのプロトコルモジュールの高度な形式IUPLua のコンストラクターなど、Luaの多くの場所で見られます。)

関数自体には、次のような署名があります。

function myfunction(t)
    setmetatable(t,{__index={b=7, c=5}})
    local a, b, c =
      t[1] or t.a, 
      t[2] or t.b,
      t[3] or t.c
    -- function continues down here...
end

パラメータのテーブルにない値は、メタテーブルの__indexテーブルから取得されます( メタテーブルのドキュメント を参照)。

もちろん、テーブルコンストラクターと関数を使用すると、より高度なパラメータースタイルを使用できます。必要なものは何でも作成できます。たとえば、 here は、パラメータ名とデフォルト値を定義するテーブルから名前付きまたは位置引数テーブルを取得する関数と、通常の引数リストを取得する関数を構築する関数です。

非言語レベルの機能として、そのような呼び出しを変更して、新しい動作とセマンティクスを提供できます。

  • 複数の名前を受け入れるように変数を作成できます
  • 位置変数とキーワード変数を散在させることができます-両方を定義すると、どちらかが優先されます(またはエラーが発生します)
  • 名前なしの位置のみの変数と同様に、キーワードのみの位置なしの変数を作成できます
  • 文字列を解析することで、かなり冗長なテーブル構築を行うことができます
  • 関数が1つのテーブル以外で呼び出された場合、引数リストはそのまま使用できます。

引数トランスレーターを作成するための便利な関数には、unpack(5.2でtable.unpackに移行)、setfenv(5.2で新しい_ENV構造で非推奨)、およびselect(指定された引数リストから単一の値を返すか、'#'でリストの長さを返します)。

80

私の意見では、別の方法はありません。それは単なるLuaの考え方です。フリルはなく、いくつかの構文糖を除いて、単純なことを行う冗長な方法はありません。

44
jpjacobs

技術的にはb = b == nil and 7 or bがあります(false or 7が7と評価されるときにfalseが有効な値である場合に使用する必要があります)が、おそらくあなたが探しているものではありません。

20

私がこれまでに見つけた意味のある唯一の方法は、このようなことをすることです:

function new(params)
  params = params or {}
  options = {
    name = "Object name"
  }

  for k,v in pairs(params) do options[k] = v end

  some_var = options.name
end

new({ name = "test" })
new()
5
NineBlindEyes