3

这有效...

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存在。给定的变量在前一行中检索。应用程序运行时出现的错误是:

unprotected error to call in Lua API(script path...: Did not pass boolean to SetNoClip).

SetNoClip 是应用程序中的一个函数,它通过lua_toboolean.

那么为什么第一个工作,第二个和第三个返回错误呢?

编辑:

SetNoClip这个定义。

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,它将返回布尔值未通过。我刚刚删除了对布尔文字的错误检查,因为人们(包括我)通常依赖于不是布尔文字的参数被正确地视为布尔值。

4

3 回答 3

1

如果该and值被认为不正确,则运算符返回其第一个参数,否则返回其第二个参数。

or如果它被认为是真的,则运算符返回它的第一个参数,否则返回它的第二个参数。

因此,A or (B and C)理论上可以返回以下任何内容:

  • AifA是一个被认为是真的值
  • BifB是一个被认为是假的值并且A被认为是假的
  • C如果以上都不是

请注意AB, 和C不需要是实际的布尔值 - 只有可以解释为布尔值的东西。由于nil被认为是错误值,因此您可能会发生第二种情况,并且传递给的参数SetNoClipnil而不是trueor false

解决此问题的一种选择是显式与 nil 进行比较,而不仅仅是使用对象:

( otherObj ~= nil and otherObj:GetType() == "IceBlock" )

因为~=运算符保证返回一个布尔值。

于 2010-07-11T17:54:51.067 回答
1

如您所见,任何对象在 Lua 中都可以有布尔解释。因此,如果您只希望传递一个布尔对象,那么您的 LuaSetNoClip 实现不符合 Lua 的精神和实践。你应该lua_toboolean直接使用。

我认为您可以合理进行的唯一参数检查是luaL_checkany

int GameObject::LuaSetNoClip( lua_State *L ) {
  luaL_checkany(L, 1);
  m_noClip = lua_toboolean( L, 1 );
  return 0;
}
于 2010-07-12T00:24:26.820 回答
0

这取决于 SetNoClip 内部发生的情况(即这通常不会引起问题)。但是,我很确定问题出在这个问题上,andor返回任一侧的值,而不是评估到trueor false。换句话说,

foo and bar

foo如果foonilor则返回false,否则返回bar

在您的情况下,原始代码传递true或传递false给 SetNoClip,而在其他示例中,您传递"water"或传递给 SetNoClip 的布尔值。SetNoClip 可能会卡在字符串上。

于 2010-07-11T17:49:00.730 回答