有一个等效于tostring()的Lua API函数,还是我必须在我的C代码中执行以下操作?
lua_getglobal(L, "tostring");
// ... push value to convert, and:
lua_call(L, 1, 1);
Run Code Online (Sandbox Code Playgroud)
长篇故事:
我正在alert(message)用C语言编写一个函数(可以从Lua调用),它将向用户显示一条消息.但如果message不是一个字符串(例如,布尔值或零),我想将其转换为理智的东西.有一个Lua函数可以做到这一点,tostring()但我想知道Lua的C API是否提供了"直接"的方法来实现这一点.
我有两个字符串.其中一个经常(但不总是)是空的.另一个是巨大的:
a = ""
b = "... huge string ..."
Run Code Online (Sandbox Code Playgroud)
我需要连接两个字符串.所以我做了以下事情:
return a .. b
Run Code Online (Sandbox Code Playgroud)
但是,如果a是空的,这将暂时不必要地创建一个巨大字符串的副本.
所以我想把它写成如下:
return (a == "" and b) or (a .. b)
Run Code Online (Sandbox Code Playgroud)
这样可以解决问题.但是,我想知道:Lua是否优化了涉及空字符串的串联?也就是说,如果我们写a .. b,Lua是否检查其中一个字符串是否为空并立即返回另一个字符串?如果是这样,我可以简单地编写a ..b代替更精细的代码.
假设我们需要将一些参数传递给shell命令.(让我们假设一个Bourne兼容shell.)
例如,假设我们要He said "It's a boy"; sure使用echo(1)打印字符串.
当然,我们不能这样做:
s = [[He said "It's a boy"; sure]]
os.execute("echo " .. s)
Run Code Online (Sandbox Code Playgroud)
但以下工作正常:
s = [[He said "It's a boy"; sure]]
os.execute(("echo %q"):format(s))
Run Code Online (Sandbox Code Playgroud)
我的问题:您认为使用%q引用shell参数是否足够好?
我已经知道%q如果我们的参数包含换行符(它将转换为斜杠+换行符,这意味着shell将看不到任何字符;但至少它不会破坏命令)并不是很好.这是针对我们的一个案例.还有其他情况%q会让我们失望吗?
Lua的当前版本不支持整数,只支持浮点数.(随着即将到来的5.3这种情况正在改变,但让我们忽略这一点.)
所以,我的问题是:有什么用处lua_pushinteger()?如果数字被投入浮动,为什么不lua_pushnumber()直接使用?
(请不要回答"为了将来与5.3的兼容性",这对今天来说是一个很好的答案,但是这个答案不能满足我的风格:过去不期望整数支持.我想知道理由lua_pushinteger()是首先引入的,后见之明不是道歉.)
我有一个关于GLib的简单问题.
我有以下代码:
static const char *words[] = { "one", "two", "three", NULL };
void main() {
puts(g_strjoinv("+", words));
}
Run Code Online (Sandbox Code Playgroud)
此代码打印one+two+three.它使用连接字符串的GLib函数.
该功能的签名是:
char *g_strjoinv (const char *separator, char **str_array);
Run Code Online (Sandbox Code Playgroud)
(确切地说,GLib使用的gchar不是char,但让我们忽略它.)
现在,我想知道为什么参数是char **str_array和不const char **str_array.它迫使我做一个显式的强制转换来摆脱编译器的警告("期望'char**'但参数类型为'const char**'"):
puts(g_strjoinv("+", (char **)words));
Run Code Online (Sandbox Code Playgroud)
我查看了GLib的参考资料,我发现所有函数都是这样定义的:它们接受char **,而不是const char **.
这是为什么?为什么GLib不使用const char **?
需要使用显式转换来摆脱const使得我的代码不那么安全(因为编译器不再检查参数的兼容性).这也让我感到紧张,因为GLib没有"签订合同",说它不会改变我的数据.
我有以下形式的字符串:
cake!apple!
apple!
cake!juice!apple!cake!
juice!cake!
Run Code Online (Sandbox Code Playgroud)
换句话说,这些字符串由三个子串"cake!","apple!"和"juice!".
我需要验证这些字符串.因此,使用正则表达式执行此操作的方法是:
/^(apple!|juice!|cake!)*$/
Run Code Online (Sandbox Code Playgroud)
但是Lua的模式没有|运算符,所以它似乎无法以这种方式完成.
如何在Lua中验证我的字符串?
(我不关心字符串的内容:我只关心它们是否符合(验证).)
我知道编写代码来做到这一点,但我想不出一个简短的方法来做到这一点.我正在寻找一个简短的解决方案.我想知道是否有一个我不知道的优雅解决方案.有任何想法吗?
我有一个简单迭代器的非常简单的问题.
假设我设计了一个files()迭代文件夹中所有文件的函数:
for file in files("/path/to/folder") do
print(file)
end
Run Code Online (Sandbox Code Playgroud)
现在,这似乎很完美,但这里有一个问题:如果文件夹不存在,或者我们没有读取权限怎么办?
我们如何表明这样的错误?
一种解决方案是在这种情况下files()返回nil, "no read permission".然后我们可以将调用包装到files()内部assert():
for file in assert(files("/path/to/folder")) do
print(file)
end
Run Code Online (Sandbox Code Playgroud)
这似乎解决了这个问题.但这迫使我们的用户始终使用assert().如果用户不关心错误怎么办?对于这种类型的用户,我们希望我们files()的行为就像文件夹是空的一样.但Lua --in case files()表示错误 - 会尝试调用返回的nil,这将导致错误("尝试调用nil值").
所以,
我们如何设计迭代器,files()以满足关心错误的用户和不关心错误的用户?
如果不可能,你会建议什么选择?
假设我有一个序列:
a = { 10, 12, 13 }
Run Code Online (Sandbox Code Playgroud)
该#a序列的长度()为3.
现在,假设我执行以下操作:
table.insert(a, nil)
Run Code Online (Sandbox Code Playgroud)
(或a[#a+1] = nil.)
这会以任何方式影响桌面吗?
这个问题的答案是决定性的,还是这种"未定义的行为"?
在Luas上我检查过(Lua 5.1,Lua 5.3)这不会影响表格.但我想知道这是否是我不能依赖的"未定义行为".
该手册仅讨论在序列nil的中间添加一个,但它没有(根据我的解释)谈论将它添加到序列的末尾.
我有以下函数只返回其字符串参数:
function N_(s)
return s
end
Run Code Online (Sandbox Code Playgroud)
您可以从gettext中识别此函数名称.它只是.pot提取器的好处的标记.
在C或Lua中实现N_()会更有效吗?
你能给我一个经验法则吗?
另一个问题:
假设我的函数有点复杂:
function Z_(s)
return dict[s] or s
end
Run Code Online (Sandbox Code Playgroud)
在C或Lua中实现Z_()会更有效吗?
(我将从Lua代码中调用N_()和Z_(),而不是从C代码调用.)
有一个常见的习惯用于遍历字符串,其字符可以使用正则表达式使用反斜杠进行转义(\\.|.),如下所示:
alert( "some\\astring".replace(/(\\.|.)/g, "[$1]") )
Run Code Online (Sandbox Code Playgroud)
这是在JavaScript中.此代码将字符串更改some\astring为[s][o][m][e][\a][s][t][r][i][n][g].
我知道Lua模式不支持OR运算符,因此我们无法将此正则表达式直接转换为Lua模式.
然而,我想知道:是否有另一种方法可以使用Lua模式在Lua中执行此操作(遍历可能转义的字符)?