91

在许多语言中,您可以在变量赋值上连接字符串。我有一个场景,使用 Lua 编程语言,我需要将命令的输出附加到现有变量。Lua 中是否有与以下示例等效的功能?

其他语言示例:

===== PERL =====
$filename = "checkbook";
$filename .= ".tmp";
================

===== C# =====
string filename = "checkbook";
filename += ".tmp";
===============

预先感谢您的帮助。

4

5 回答 5

142

正如其他答案所说,Lua 中的字符串连接运算符是两个点。

您的简单示例将这样编写:

filename = "checkbook"
filename = filename .. ".tmp"

但是,有一点需要注意。由于 Lua 中的字符串是不可变的,因此每次连接都会创建一个新的字符串对象并将数据从源字符串复制到它。这使得对单个字符串的连续连接具有非常差的性能。

这种情况下的 Lua 习惯用法是这样的:

function listvalues(s)
    local t = { }
    for k,v in ipairs(s) do
        t[#t+1] = tostring(v)
    end
    return table.concat(t,"\n")
end

通过将要连接的字符串收集到一个数组t中,可以使用标准库例程table.concat将它们全部连接起来(以及每对之间的分隔符字符串),而无需进行不必要的字符串复制。

更新:我刚刚注意到我最初使用pairs()而不是ipairs().

正如最初编写的那样,该函数listvalues()确实会从传入的表中生成每个值,但不是以稳定或可预测的顺序。另一方面,它将包括在 to 范围内的键不是正整数的1#s。这就是这样pairs()做的:它生成存储在表中的每一个(键,值)对。

在大多数情况下,您将使用类似listvaluas()您对保留其顺序感兴趣的东西。因此,编写为 as 的调用listvalues{13, 42, 17, 4}将生成一个包含该顺序的值的字符串。但是,pairs()不会那样做,它会以某种顺序逐项列出它们,这取决于表数据结构的底层实现。众所周知,顺序不仅取决于密钥,还取决于插入密钥和移除其他密钥的顺序。

当然ipairs()也不是一个完美的答案。它仅枚举形成“序列”的表的那些值。也就是说,那些作为键的值形成了一个从 1 到某个上限的完整块,该上限(通常)也是#运算符返回的值。(在许多情况下,函数ipairs()本身最好用一个从tofor计数的更简单的循环来代替。这是 Lua 5.2 和 LuaJIT 中推荐的做法,其中更简单的循环可以比迭代器更有效地实现。)1#sforipairs()

如果pairs()确实是正确的方法,那么通常情况下您希望同时打印键和值。这通过使数据自描述来减少对顺序的担忧。当然,由于任何 Lua 类型(nil浮点数除外NaN)都可以用作键(NaN也可以存储为值),因此查找字符串表示形式留给学生作为练习。不要忘记树和更复杂的表格结构。

于 2009-09-10T19:19:23.723 回答
22

如果您问是否有 operator 的简写版本..- 不,没有。你不能写a ..= b。您必须完整输入:filename = filename .. ".tmp"

于 2009-09-10T16:39:01.947 回答
8

级联:

Lua 中的字符串连接运算符用两个点('..')表示。如果两个操作数都是字符串或数字,则根据第 2.2.1 节中提到的规则将它们转换为字符串。否则,调用“concat”元方法(参见 §2.8)。

来自:http ://www.lua.org/manual/5.1/manual.html#2.5.4

于 2009-09-10T14:29:36.273 回答
3

可以使用连接运算符“..”将字符串连接在一起

这对于我认为的变量是一样的

于 2009-09-10T14:29:11.907 回答
2

在其他语言中,您将使用:

// C#

string a = "Hello";

// 2 Options
a = a + " World!";

// or the easier way:
a += " World!";

现在在 Lua 中:你会使用.., 这里的一个例子:

-- Lua

local a = "Hello"

-- Sadly Lua doesn't have += so you have to do it this way.
a = a.." World!";
于 2021-08-24T18:12:01.973 回答