Lua源代码是否采用了清晰易懂的编写规范?

我最近在阅读Lua编程语言的源代码,发现其中有一些约定不太清晰或令人困惑。例如,在此文件中的str_reverse函数。在C中,它是否被认为是清晰易懂的代码?

static int str_reverse (lua_State *L) {
   size_t l, i;
   luaL_Buffer b;
   const char *s = luaL_checklstring(L, 1, &l);
   char *p = luaL_buffinitsize(L, &b, l);
   for (i = 0; i < l; i++)
       p[i] = s[l - i - 1];
   luaL_pushresultsize(&b, l);
   return 1;
}

在这些代码中:

char *p = luaL_buffinitsize(L, &b, l);
for (i = 0; i < l; i++)
   p[i] = s[l - i - 1];

*p被创建用于存储反转后的字符串值。之后,我没有看到它在任何其他地方被使用。然后看看char *p = luaL_buffinitsize(L, &b, l);,它表明*pluaL_Buffer b;的一个属性,这也解释了为什么*p不再使用了,因为在下一行中,b正在使用。

此外,在这行代码const char *s = luaL_checklstring(L, 1, &l);中,luaL_checklstring函数返回的是*s,同时将字符串的长度(从L中获取的)赋值给size_t l变量。因此,此函数不仅返回1个变量,而且在其途中还改变了1个变量的值。

点赞
用户722238
用户722238

当你不知道某个东西是如何工作的时候,认为它可能写得很差是合理的。然而,上面的代码是可读的。我不知道 Lua 和 C 干什么,但我能够解密其中发生的事情。

第一件可能会帮助你的事情是了解 str_reverse 如何被调用。启动一个解释器:

> str = "foo"         /* create a string in a lua state */
> string.reverse(str) /* indirectly invokes str_reverse */
oof                   /* result */

str_reverse 做的第一件事是调用 luaL_checklstring,它是 lua_tolstring 的包装函数,添加了错误检查。在对话中:

str_reverseluaL_checklstring 说:

“嘿,我需要一个字符串 - 给我地址(将其存储在 s 中),我还需要长度(将其存储在 l 中)。”

luaL_checklstring 说:“是的,一切都很好 - 给你!”

你看,C 语言需要知道所有东西的大小,这样它才能分配正确的内存。因为 str_reverse 需要为反转的字符串分配内存(更准确地说是,如果 luaL_Buffer b 太小而无法容纳字符串,则需要调整大小),它告诉 luaL_checklstring 同时提供长度。如果 str_reverse 不关心长度,则传递 NULL 而不是 l。这就是 Lua API 的设计方式 - 对我来说看起来很易读。

p 并不存储字符串的值 - 反转后的字符串存储在 b 中,作为成员。 p 基本上是一个快捷方式,考虑以下内容:

/* disregard the pointer returned by buffinitsize */
luaL_buffinitsize(L, &b, l);
for (i = 0; i < l; i++)
    b->b[i] = s[l - i - 1];

上述代码应该是相同的。除了现在,暴露了 luaL_Buffer 的细节......不是很好。

你需要了解指针。如果不了解指针,你将永远无法完全理解 C,这就像没有脚走路。

总之,很遗憾你被 down-voted 这么多,可能是因为你选择的问题标题 - 听起来像是你在抨击 Lua。除此之外,你的问题似乎是真诚的 - 祝你好运,并在阅读其他人的代码的冒险中玩得开心!

2018-11-28 10:16:49