lua的深拷贝和浅拷贝
--- Deep copies a table into a new table.
-- Tables used as keys are also deep copied, as are metatables
-- @param orig The table to copy
-- @return Returns a copy of the input table
local function deep_copy(orig)
local copy
if type(orig) == "table" then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[deep_copy(orig_key)] = deep_copy(orig_value)
end
setmetatable(copy, deep_copy(getmetatable(orig)))
else
copy = orig
end
return copy
end
--- Copies a table into a new table.
-- neither sub tables nor metatables will be copied.
-- @param orig The table to copy
-- @return Returns a copy of the input table
local function shallow_copy(orig)
local copy
if type(orig) == "table" then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[orig_key] = orig_value
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
例子如下:
local a = { aa = 1, bb = 2, cc = { dd = { ee = 3 } } }
--local b = deep_copy(a)
local b = shallow_copy(a)
b.cc.dd.ee = 111
b.bb = 111
ngx.say(cjson.encode(a))
ngx.say(cjson.encode(b))
结果:{"aa":1,"bb":2,"cc":{"dd":{"ee":111}}}
{"aa":1,"bb":111,"cc":{"dd":{"ee":111}}}
- 浅拷贝修改拷贝的某个键对应的值并不影响原始的表的键对应值(只能作用于第一层,如果多层嵌套就会导致原始表被修改)
local men = { mkey = 555 }
local a = { aa = 1, bb = 2, cc = { dd = { ee = { ff = 3 } } } }
setmetatable(a, { __index = men })
local b = deep_copy(a)
ngx.say(a.cc.dd.ee.ff)
ngx.say(a.mkey)
ngx.say(b.mkey)
3
555
555
- 这个深拷贝可以同时复制原始表的元表。如果不许要可以将
setmetatable(copy, deep_copy(getmetatable(orig)))去掉。
lua的深拷贝和浅拷贝的更多相关文章
- C#设计模式:原型模式(Prototype)及深拷贝、浅拷贝
原型模式(Prototype) 定义: 原型模式:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.被复制的实例被称为原型,这个原型是可定制的. Prototype Pattern也是一 ...
- Objective-C中的深拷贝和浅拷贝
在Objective-C中对象之间的拷贝分为浅拷贝和深拷贝.说白了,对非容器类的浅拷贝就是拷贝对象的地址,对象里面存的内容仍然是一份,没有新的内存被分配.对非容器类的深拷贝就是重写分配一块内存,然后把 ...
- $.extend()的深拷贝和浅拷贝详细讲解
版权声明:作者原创,转载请注明出处! 语法:jQuery.extend( [deep ], target, object1 [, objectN ] ) 描述: 将两个或更多对象的内容合并到第一个对象 ...
- JavaScript中面向对象的的深拷贝和浅拷贝
理解深拷贝和浅拷贝之前需要弄懂一些基础概念,内存中存储的变量类型分为值类型和引用类型. 1.值类型赋值的存储特点, 将变量内的数据全部拷贝一份, 存储给新的变量. 例如:var num = 123 : ...
- C++深拷贝与浅拷贝
当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用.也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用.以下情况都会调用拷贝构造函数: (1)一个对 ...
- C++的深拷贝与浅拷贝
对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面是一个类对象拷贝的简单例子. #i ...
- Python赋值语句与深拷贝、浅拷贝的区别
参考:http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-d ...
- [C#进阶系列]专题一:深入解析深拷贝和浅拷贝
一.前言 这个星期参加了一个面试,面试中问到深浅拷贝的区别,然后我就简单了讲述了它们的之间的区别,然后面试官又继续问,如何实现一个深拷贝呢?当时只回答回答了一种方式,就是使用反射,然后面试官提示还可以 ...
- 也来玩玩 javascript对象深拷贝,浅拷贝
经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One method of copying an object is ...
随机推荐
- 孤荷凌寒自学python第十一天初识Python的字典类
孤荷凌寒自学python第十一天初识Python的字典类 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) Python的字典其实是一张二维对照表 下面举例说明: 键名Key 姓名 性别 身高 ...
- SPOJ 364 Pocket Money 简单DP
跟矩阵链乘同类型的题…… 输出用%llu不是%I64u…… 几组数据: 141+2*4+3*4+5*00*5*6+7*3+23+0+6+7+0+44*5+7*1*1+12*0+3*4*0+5*6+7+ ...
- Java 多线程(Thread)学习
多线程:就是进程的扩展,实现并发.一个进程可以包含多个线程,进程一般是由操作系统控制,而线程就是由程序员控制的,所以作为编程人员做好线程是我们的重点. 线程和进程一样分为五个阶段:创建.就绪.运行.阻 ...
- 移动平台自动化测试:appium(一)
Appium 是一个开源的,跨平台的自动化测试工具.它支持模拟器(iOS,FirefoxOS,Android)和真机(iOS, Android, FirefoxOS)上的原生应用,混合应用和移动 we ...
- 第十一篇:MySQL基础
本篇内容 MySQL概述 MySQL安装 MySQL库增.删.改.查 MySQL表增.删.改.查 MySQL表记录增.删.改.查 一. MySQL概述 MySQL是一个关系型数据库管理系统,由瑞典 M ...
- BZOJ 3932: [CQOI2015]任务查询系统 | 主席树练习题
题目: 洛谷也能评测 题解: De了好长时间BUG发现是自己sort前面有一行for没删,气死. 题目询问第x秒时候前k小的P值之和. 朴素想法: 我们可以把P值离散化,然后对于每个时刻建一棵定义域是 ...
- Batting Practice LightOJ - 1408
Batting Practice LightOJ - 1408(概率dp) 题意:有无限个球,进球的概率为p,问你连续不进k1个球或者连续进k2个球需要使用的球的个数的期望 思路: \(定义f[i]表 ...
- Java面试题之类的静态代码块和静态属性等的加载顺序
如以下面试题: /** * @author hjs * @date 2019/3/62:41 * @Dec */public class B { public static B t1 = new B( ...
- git的回退和撤销操作
回退是git的使用中很常用的一个操作,如果清楚各个回退命令的作用,不仅大大加快代码回退的效率,还能避免代码回退造成的事故 1.git reset --hard [commit] 清空暂存和未暂存的更改 ...
- linux mint 自动挂载windows的D盘和E盘
终端敲udisksctl mount -p block_devices/sda后双击tab键补全分区,如下: 如我的E盘是sda6,执行 udisksctl mount -p block ...