细数lua那些坑

    因为公司用的LUA版本是5.0,自己一般用5.1,所以说的是这两个版本的坑。

1、不支持continue,因为没有这个关键字,有时候写代码有些麻烦

2、TABLE的排序,在有相同元素的情况下,排序结果不正确。

       由于采用的是快速排序,在有相同元素的情况下,影响了比大小时的判断,导致排序结果出错。其实可以用一些代码进行修改。

       代码如下:

static void auxsort (lua_State *L, int l, int u) {
  while (l < u) {  /* for tail recursion */
    int i, j;
	// 以下代码为找一个合适的中值作为快速排序的基准值
    /* sort elements a[l], a[(l+u)/2] and a[u] */
    lua_rawgeti(L, 1, l);
    lua_rawgeti(L, 1, u);
    if (sort_comp(L, -1, -2))  /* a[u] < a[l]? */
      set2(L, l, u);  /* swap a[l] - a[u] */
    else
      lua_pop(L, 2);
    if (u-l == 1) break;  /* only 2 elements */
    i = (l+u)/2;
    lua_rawgeti(L, 1, i);
    lua_rawgeti(L, 1, l);
    if (sort_comp(L, -2, -1))  /* a[i]<a[l]? */
      set2(L, i, l);
    else {
      lua_pop(L, 1);  /* remove a[l] */
      lua_rawgeti(L, 1, u);
      if (sort_comp(L, -1, -2))  /* a[u]<a[i]? */
        set2(L, i, u);
      else
        lua_pop(L, 2);
    }
	// 以上代码为找基准值的过程, 基准值为i
    if (u-l == 2) break;  /* only 3 elements */
    lua_rawgeti(L, 1, i);  /* Pivot */
    lua_pushvalue(L, -1);
    lua_rawgeti(L, 1, u-1);
    set2(L, i, u-1);
    /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
    i = l; j = u-1;
    for (;;) {  /* invariant: a[l..i] <= P <= a[j..u] */
      /* repeat ++i until a[i] >= P */
		while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
        if (i>u) luaL_error(L, "invalid order function for sorting");
		if(i>=u-1)
		{
			break;
		}
        lua_pop(L, 1);  /* remove a[i] */
		
      }
      /* repeat --j until a[j] <= P */
      while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
        if (j<l) luaL_error(L, "invalid order function for sorting");
		if (j==l)
		{
			break;
		}
        lua_pop(L, 1);  /* remove a[j] */
      }
      if (j<i) {
        lua_pop(L, 3);  /* pop pivot, a[i], a[j] */
        break;
      }
      set2(L, i, j);
    }
	if (i!=u-1)
	{
		lua_rawgeti(L, 1, u-1);
		lua_rawgeti(L, 1, i);
		set2(L, u-1, i);  /* swap pivot (a[u-1]) with a[i] */
	}
    
    /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
    /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
    if (i-l < u-i) {
      j=l; i=i-1; l=i+2;
    }
    else {
      j=i+1; i=u; u=j-2;
    }
    auxsort(L, j, i);  /* call recursively the smaller one */
  }  /* repeat the routine for the larger one */
}

3、一个较大的数调用tostring()之后,再调用tonumber(),得到的值不是原来的值了。从代码可以看出只能容下14位小数位,所以有时候数字会被截断变小。

#define LUA_NUMBER_FMT "%.14g"

#define lua_number2str(s,n)    sprintf((s), LUA_NUMBER_FMT, (n))


4、函数调用层次、参数个数等等经常会有一个最大数的限制,如果不小心超过了。。。。。


5、LUA的TABLE分为数组和HASH两个部分,很多的库函数是针对把TABLE当作严格的数组时起作用的。如果误用的话,结果通常是不准确的。

6、LUA 5.1的变量默认是全局的,很容易在函数中的变量没有加上local而覆盖全局的变量,而导致全局数据变化,逻辑不正确。

7、LUA代码执行如果出现错误会停止执行函数后面的代码,会导致需要严格控制的流程只执行了一部分,产生逻辑错误。例如在网游中购买商品的过程中,如果先给物品,再扣钱。代码在给完物品后出现错误,就不会执行扣除金钱的操作,导致可在无限地利用这个漏洞刷物品。 对于这类情况,一般是先检测金钱数是否够,条件是否满足,先扣钱,再给物品,并记录下日志。这样如果出现错误,玩家损失了金钱,但是可以找客服进行解决。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值