Varargsは一般的に知られているように、関数が指定なしで任意の数の引数を取ることを可能にします。そのような関数に与えられたすべての引数は、 varargリストと呼ばれる単一の構造体にパッケージ化されています 。ルアには...
と書かれてい...
。 select()
関数を使用して、与えられた引数の数とそれらの引数の値を抽出する基本的な方法がありselect()
が、より高度な使用パターンは構造を完全に活用することができます。
効率
varargリストは言語のPUC-Rio実装のリンクリストとして実装されます。つまり、インデックスはO(n)です。これは、以下の例のように、 select()
を使用してvarargの要素を反復処理することは、O(n ^ 2)操作であることを意味します。
for i = 1, select('#', ...) do
print(select(i, ...))
end
varargリストの要素を反復処理する場合は、まずリストを表にパックします。テーブルへのアクセスはO(1)なので、反復はO(n)です。または、もしあなたがそう思っているなら、高度な使い方のセクションのfoldr()
例を見てください。 O(n)のvarargリストを反復するために再帰を使用します。
シーケンス長の定義
varargは、varargの長さが明示的に渡された(または計算された)nilsを尊重する点で有用です。例えば。
function test(...)
return select('#', ...)
end
test() --> 0
test(nil, 1, nil) --> 3
ただし、この動作はテーブルの動作と競合します。ただし、length演算子#
は 'holes'(埋め込みnils)で動作しません。穴のあるテーブルの長さを計算することは定義されておらず、信頼できません。したがって、 ...
の値に応じて、 {...}
長さを取っても「正しい」答えが得られないことがあります。 Lua 5.2+では、 table.pack()
がこの欠点を処理するために導入されました(純粋なLuaでこの関数を実装する関数には関数があります)。
慣用的な使用
可変長はその長さを持ち歩くので、テーブルの穴に問題が発生するのを避けるために、それらをシーケンスとして使用します。これは、意図された使用法ではなく、Luaのリファレンス実装が最適化しないものでした。このような使用法は、例で検討されていますが、一般的に眉をひそめます。