【问题标题】:Lua override # for stringsLua 覆盖 # 用于字符串
【发布时间】:2014-04-16 00:00:19
【问题描述】:

我正在尝试在 Lua 中实现我自己的字符串长度方法。 我已经成功地覆盖了字符串的 len() 方法,但我不知道如何为 # 运算符执行此操作。

orig_len = string.len
function my_len(s)
  print(s)
  return orig_len(s)
end

string.len = my_len
abc = 'abc'

如果我打电话:

print(abc:len())

它输出:

abc
3

但是

print(#abc)

仅输出“3”,这意味着它称为原始长度函数而不是我的。有没有办法让#调用我的长度函数?

【问题讨论】:

    标签: lua operator-overloading metatable meta-method


    【解决方案1】:

    您不能在 Lua 中为字符串覆盖 # 运算符,即使是元表也不行:__len 元方法不适用于字符串。

    事实上,在 Lua 中确实没有覆盖任何操作符的概念。 Lua 元方法是 fallbacks:当 Lua 无法自行进行时使用它们。因此,算术元方法不适用于数字,长度元方法不适用于字符串。

    表的情况有所不同,因为它们是用来在 Lua 中实现对象的。

    【讨论】:

    • 那么,有没有办法做我需要的?
    • @Xanx,不,除非你想用表格包装字符串。
    【解决方案2】:

    我正在尝试在 Lua 中实现我自己的字符串长度方法。

    你不能在 Lua 中做到这一点。

    您需要修改 Lua 源代码,特别是虚拟机 (lvm.c) 并更改其对操作码 OP_LEN 的处理。在 Lua 5.2 中,您需要更改 luaV_objlen 以在获取字符串的实际长度之前检查元方法:

    case LUA_TSTRING: {
      tm = luaT_gettmbyobj(L, rb, TM_LEN);        // <--- add this line
      if (!ttisnil(tm))                           // <--- add this line
          break;                                  // <--- add this line
      setnvalue(ra, cast_num(tsvalue(rb)->len));
      return;
    }
    

    但这似乎是运算符重载滥用,例如重载+ 以表示除法之类的。

    【讨论】:

    • 滥用是对的。 Lua 字符串是字节字符串而不是字符串。当然,在给定语言环境的情况下,有些函数会将它们解释为字符,但字符串的长度不应被视为字节数以外的任何东西。
    • 好吧,我需要让 Lua 像原生一样处理 utf-8 字符串。我可以为此创建函数,例如 strlenstrsub,但我希望 utf-8 处理对程序员来说是透明的,所以我需要 Lua 字符串函数来处理 utf-8。
    • 我相信这是 Lua 5.3 的一个特性。
    猜你喜欢
    • 1970-01-01
    • 2019-08-22
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多