luaのandとor

7303 ワード

luaのandとorの巧みな使い方はとっくに知っていた.
local str = num==1 and "one" or "not one"

この言葉は以下の意味を簡潔に表すことができます.
local str = ""
if num==1 then
    str = "one"
else
    str = "not one"
end

c++に似ています:?演算子は、ずっと使っていて問題ありませんが、先日奇妙なバグに遭遇しました.最後に調べてみると、この使い方にロックされています.例を挙げます.
function get_item(config_id, star_lv, server_id)
    for _,item in pairs(items) do
        if item.config_id==config_id and item.star_lv==star_lv and (server_id and item.server_id==server_id or true) then
            return item
        end
    end
end

config_によるとid, star_lvとserver_idは物を探しに来ましたserver_idは記入しなくてもよい(すなわちnil)、記入しなければ無視する.論理的には正しいが、実行時にバグがある.なぜなら、server_id and item.server_id=server_id or trueという文である.元々luaのandとorが返す値は、その最終値の値を特定できるようにする値である
簡単にテストすると法則がわかります.
print(false and nil)    -- false
print(nil and true)     -- nil
print(123 and nil)      -- nil
print(123 and 456)      -- 456
print(false or nil)     -- nil
print(nil or 123)       -- 123
print(123 or nil)       -- 123
print(123 or 456)       -- 123

bool値ではなく値を返すことを検証するために、falseの代わりにnilを使用し、trueの代わりに123456を使用した.a=b and c or dという書き方は、a=(b and c)or d、すなわちb and cに基づいてdを返すかどうかを決定する.結果は明らかで、b and cには2つの状況があります.
b:true -> c
b:false -> b
それからdと論理あるいは演算をします:x or d、x or dは:
x:true -> x
x:false -> d
ここまで解析すると,a=b and c or dの場合,
b:true ->
c:true -> a = c
c:false -> a = d

b:false -> a = d
ピットはすでに露出して、a=b and c or dはC++のa=bと等しくありませんか?c:dはcがtrueの場合にのみ使用できます