2017-01-20 1 views
1

私はunpack(4)またはunpack("hello world")としましょう。これに予期しない動作がありますか?Luaで簡単な値をアンパックしない理由はありますか

function a(bool) 
    if bool then 
    return {1, 2}, "foo" 
    else 
    return 1, "foo" 
    end 
end 

function b(x, z) 
end 

function b(x, y, z) 
end 

i, j = a(???) 
b(unpack(i), j) -- is this ok? 
+1

あなたはコードを実行し、何が起こるかを尋ねる代わりに何が起こるかを見ることができますか? – Piglet

+1

'b(unpack(i)、j)'を学ぶもっと良い方法は悪い例です: 'unpack(i)'の結果は一つの値に調整されます。 –

+1

すべてのケースでテーブルを返す最も簡単な方法はありませんか?したがって、返される値が1つある場合は、 'return {1}、' foo "'のようにします – tonypdmtr

答えて

2

unpack(4)

unpack("hello world")数値の長さを取得するには、エラー

試みが

を返しますが発生します。このようなものがある

理由

はnil nilにはnil nilにはnil nilにはnil nilにはnil nilの

nilのようにも非常に便利ではありません。

unpackはアンパックテーブル用です。

Luaがオーバーロードした機能をサポートしていません:あなたはLuaの最近のバージョンで作業したい場合は、今、あなたのコードでtable.unpack()

その他の問題であることに気づくでしょう。関数は変数です。

あなたが書く:2番目の定義が処理されると

function b(x, z) 
end 

function b(x, y, z) 
end 

最初の定義は失われます。 別の表記を使用すると、より明確になります。 あなたのコードが

b = function (x, z) 
end 

b = function (x, y, z) 
end 

と同等であると私はあなたが

b = 3 
b = 4 

b後4.同じ原理になることに同意すると思う...

+1

関数定義を上書きしようとしているところがありますが、 'Luaは関数のオーバーロードをサポートしていません'それは同じ効果を別のやり方で可能にするからです。たとえば、任意の数または型の引数を渡すことが許可されていると、効果的に同じように機能します。あなたの例では、 '関数b(x、y、z)'は、 'z'が' nil'のとき '関数b(x、y)'として働くことができます。関数の追加バージョンを後で(すなわち別々に)定義する必要がある場合は、次のように元の関数を常にフロントエンドすることができます: 'local b = function(x、y、z)b(x 、y)end' – tonypdmtr

+0

訂正:1)関数は変数ではなく値です。関数値は、他の値と同様に、参照がない場合は「失われています」。 2)関数定義は関数値を生成する式である。コードなので、決して紛失することはありません。 –

+1

@tonypdmtr "オーバーロード"は、バインディング解決フェーズ(コンパイラなど)がある場合にのみ意味を持ちます。ルアでは、名前は一度に誰でも1つのことを指します。各関数値は、任意の数のパラメータでいつでも呼び出すことができます。それは、それが望むような方法で望むものを扱い、残りを無視します。 –

2

あなたがにunpack標準関数を修正することができます希望の行動を得る:

local old_unpack = table.unpack or unpack 

local function new_unpack(list, ...) 
    if type(list) ~= "table" then 
     list = {list} 
    end 
    return old_unpack(list, ...) 
end 

table.unpack = new_unpack 
unpack = new_unpack 

-- Usage: 
print(unpack(4)) 
print(unpack("hello world")) 
print(unpack(nil)) -- ops! nothing is printed! 
関連する問題