Lua的String字符串拼接

Stella981
• 阅读 1054

每个语言都会遇到字符串拼接的问题。上回说到C#的字符串拼接Concat,我们知道C#中拼接许多字符串一般不用“+”号,因为每次+操作都会产生一个临时的字符串。所以C#里面就提供了StringBuilder--可变字符串来拼接,直到最后tostring的时候才会产生最终的string字符串。

Lua语言里面默认是”  ..“两个英文点号来表示字符串的拼接。但是当我们需要拼接多个字符串的时候,同样的思路table.concat

table.concat (list [, sep [, i [, j]]])

Lua提供一个列表,其所有元素都是字符串或数字,返回字符串 list[i]..sep..list[i+1] ··· sep..list[j]sep 的默认值是空串, i 的默认值是 1 , j 的默认值是 #list 。如果 ij 大,返回空串。

也就是说我们可以将下面这段代码

function Concat(...)    local origin = {...}    local message = ""    for i,v in pairs(origin) do       message = message .. v    end    return messageend

改成

function Concat(...)    local message = {...}    return table.concat(message)end

原理

这里参考https://www.lua.org/pil/11.6.html网站上面的示例,简单介绍一下table.concat

假设现在正在逐行读取文件

  -- WARNING: bad code ahead!!    local buff = ""    for line in io.lines() do    buff = buff .. line .. "\n"    end

Lua使用了真正的垃圾收集算法;当它检测到程序正在使用过多的内存时,它将遍历其所有数据结构并释放那些不再使用的结构(垃圾)。

让我们假设我们处于读取循环的中间。buff已经是一个50 KB的字符串,每行有20个字节。当Lua串联时buff..line.."\n",它将创建一个具有50,020字节的新字符串,并将50 KB复制buff到该新字符串中。也就是说,对于每条新行,Lua都会移动50 KB的内存并不断增长。读取100行后(仅2 KB),Lua已经移动了5 MB以上的内存。

    buff = buff .. line .. "\n"

经过两个循环之后,有两个旧字符串构成了总计超过100 KB的垃圾。因此,Lua相当正确地决定,现在是运行其垃圾收集器的好时机,因此它释放了这100 KB。问题是,这将每两个周期发生一次,因此Lua将在读取整个文件之前运行其垃圾收集器2000次。即使完成所有这些工作,它的内存使用量也将大约是文件大小的三倍。

使用concat,我们可以简单地将所有字符串收集在一个表中,然后一次将它们全部连接起来。因为concat使用C实现,所以即使对于大字符串也很有效。

然后将上面的代码改造一下

local t = {}for line in io.lines() do  table.insert(t, line)ends = table.concat(t, "\n") .. "\n"

综上:Lua连大量字符串的时候使用table.concat

参考:https://www.lua.org/pil/11.6.html

参考:http://cloudwu.github.io/lua53doc/manual.html#pdf-table.concat

本文分享自微信公众号 - Unity游戏开发笔记(UnityGameDeveloper)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
3年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Easter79 Easter79
3年前
thymeleaf在工作中遇到的问题及解决办法(四)
1、关于字符串拼接的问题       字符串拼接可以使用如下方式。<ahref""th:text"第${StartNo}页''共${countPage}页"       还有一种更优雅的方式,使用“||”减少了字符串的拼接,代码如下。<ahref""th:
Stella981 Stella981
3年前
JS 苹果手机日期显示NaN问题
问题描述newDate("2019122910:30:00")在IOS下显示为NaN原因分析带的日期IOS下存在兼容问题解决方法字符串替换letdateStr"2019122910:30:00";datedateStr.repl
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
3年前
JavaScript常用函数
1\.字符串长度截取functioncutstr(str,len){vartemp,icount0,patrn/^\x00\xff/,strre"";for(vari
Wesley13 Wesley13
3年前
unity将 -u4E00 这种 编码 转汉字 方法
 unity中直接使用 JsonMapper.ToJson(对象),取到的字符串,里面汉字可能是\\u4E00类似这种其实也不用转,服务器会通过类似fastjson发序列化的方式,将json转对象,获取对象的值就是中文但是有时服务器要求将传参中字符串中类似\\u4E00这种转汉字,就需要下面 publ
LeeFJ LeeFJ
1年前
Foxnic-SQL (13) —— 外部SQL与SQL模版
首先,大多数时候,我们的第一反应是用字符串去拼接SQL语句,这说明字符串拼接方式其实是最直观的。其次,使用对象化的方式拼接SQL,还是有其局限性,大量的SQL文本也不宜直接写在Java类中。所以,FoxnicSQL将原本要写在Java类中的SQL语句放到一个外部文件中,每个语句用一个ID去标识,在SQL执行时,只要指定ID就可以了。在此基础上,FoxnicSQL加入了模板引擎、SQL语句置换、热加载等特性,使其变得更加好用。