这有效......
if ( tileType == "water" or
( otherObj and otherObj:GetType() == "IceBlock" )) then
self:SetNoClip( true )
else
self:SetNoClip( false )
end
- 这些不......
self:SetNoClip( tileType == "water" or
( otherObj and otherObj:GetType() == "IceBlock" ))
//----------------------------------------------------------
local noClip = ( tileType == "water" or
( otherObj and otherObj:GetType == "IceBlock" ))
self:SetNoClip( noClip )
otherObj
测试只是评估otherObj是否为 nil
. 给出的变量在前一行中检索 . 我运行应用程序时遇到的错误是:
在Lua API中调用的无保护错误(脚本路径...:未将布尔值传递给SetNoClip) .
SetNoClip是应用程序中的一个函数,它通过 lua_toboolean
获取推送到lua堆栈的参数 .
那么为什么第一次工作以及第二次和第三次返回错误呢?
编辑:
SetNoClip had 这个定义 .
int GameObject::LuaSetNoClip( lua_State *L ) {
if ( !lua_isboolean( L, -1 )) {
LogLuaErr( "Did not pass boolean to SetNoClip for GameObject: " + m_type );
return luaL_error( L, "Did not pass boolean to SetNoClip" );
}
m_noClip = lua_toboolean( L, -1 );
return 0;
}
问题是 lua_isboolean
不进行任何隐式类型转换(但 lua_toboolean
确实)并且只对文字布尔值返回true . 因此,如果它看到nil,它将返回一个布尔值没有't passed. I just removed the error check for a boolean literal, since people (including me) commonly rely on arguments that aren' t布尔文字被正确地视为布尔值 .
3 回答
如果该值被认为是非真值,
and
运算符将返回其第一个参数,否则返回其第二个参数 .如果
or
运算符被认为是真的,则返回其第一个参数,否则返回其第二个参数 .因此,
A or (B and C)
理论上可以返回以下任何一项:A
如果A
是一个被认为是真的值B
如果B
是一个被认为是假的值而A
被认为是假的C
如果以上都不是这种情况请注意,
A
,B
和C
不需要是实际的布尔值 - 只能解释为布尔值 . 由于nil
被认为是假值,因此第二种情况可能发生在您身上,而传递给SetNoClip
的参数是nil
而不是true
或false
.解决这个问题的一个选择是明确地与nil进行比较,而不仅仅是使用对象:
因为
~=
运算符保证返回一个布尔值 .如您所见,任何对象都可以在Lua中使用布尔解释 . 因此,如果您希望传递一个布尔对象,那么LuaSetNoClip的实现不符合Lua的精神和实践 . 你应该直接使用
lua_toboolean
.我认为你可以合理做的唯一参数检查是
luaL_checkany
:这取决于SetNoClip内部发生了什么(也就是说,这肯定是't necessarily cause problems in general). However, I',我确定问题是
and
和or
返回两边的值而不是评估为true
或false
. 换句话说,如果
foo
是nil
或false
,则返回foo
,否则返回bar
.在您的情况下,原始代码将
true
或false
传递给SetNoClip,而在其他示例中,您要么传递"water"
,要么将布尔值传递给SetNoClip . SetNoClip可能会阻塞字符串 .