Lua 中的字符串是不可变的。这意味着,任何替换字符串中文本的解决方案最终都必须构造一个具有所需内容的新字符串。对于用其他内容替换单个字符的特定情况,您需要将原始字符串拆分为前缀部分和后缀部分,然后将它们重新连接到新内容周围。
您的代码的这种变化:
function replace_char(pos, str, r)
return str:sub(1, pos-1) .. r .. str:sub(pos+1)
end
是对简单 Lua 最直接的翻译。对于大多数用途来说,它可能足够快了。我已经修复了前缀应该是第一个的错误pos-1
字符,并利用了这样一个事实:如果最后一个参数string.sub
缺少它被认为是-1
这相当于字符串的结尾。
但请注意,它会创建许多临时字符串,这些字符串将在字符串存储中徘徊,直到垃圾收集将其吃掉。在任何解决方案中都无法避免前缀和后缀的临时性。但这也必须为第一个创建一个临时的..
由第二个操作符消耗。
两种替代方法中的一种可能会更快。第一个是Paŭlo Ebermann 提供的解决方案,但有一个小调整:
function replace_char2(pos, str, r)
return ("%s%s%s"):format(str:sub(1,pos-1), r, str:sub(pos+1))
end
这使用string.format
对结果进行组装,希望它能够猜测最终的缓冲区大小,而不需要额外的临时对象。
但请注意string.format
可能有任何问题\0
它通过的任何字符串中的字符%s
格式。具体来说,由于它是按照标准 C 实现的sprintf()
函数,期望它在第一次出现时终止替换字符串是合理的\0
。 (用户注意到妄想逻辑在评论中。)
我想到的第三种选择是:
function replace_char3(pos, str, r)
return table.concat{str:sub(1,pos-1), r, str:sub(pos+1)}
end
table.concat
有效地将字符串列表连接成最终结果。它有一个可选的第二个参数,它是要在字符串之间插入的文本,默认为""
这符合我们的目的。
我的猜测是,除非您的字符串很大并且经常进行这种替换,否则您不会看到这些方法之间有任何实际的性能差异。然而,我之前就感到惊讶,因此分析您的应用程序以验证是否存在瓶颈,并仔细对潜在的解决方案进行基准测试。