首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >lua用户数据按值传递

问lua用户数据按值传递
EN

Stack Overflow用户
提问于 2016-02-05 01:43:21
回答 1查看 1.1K关注 0票数 2

我相信你们中的一些人会遇到这个问题。我有一个名为C++的userdata对象,它使用通常的操作符重载方式编写,例如。

代码语言:javascript
复制
CMatrix<T>& operator=(const CMatrix<T>& b);
CMatrix<T>& operator=(const T& rhs);

在C++中,当我创建两个矩阵时,比如A和B,并使A=B,则A和B可以作为两个独立的对象使用。但是,在Lua中,当我编写A=B并更改B的任何属性时,A也会发生变化。

显然,从Lua手册上也可以看出,Lua通过引用用户数据来分配用户数据,从而解释了上述行为。但是,如何使A=B按值传递,以便在B更改时不影响A。

事实上,我想通过引用的方式传递A=B的赋值,这确实是非常快的,而且是Matlab所做的,但是当我第一次设置B的属性时,我想要独立地创建B,这是我的Matlab实践的结果,因为我可以根据Matlab的内存使用情况来跟踪它。

如果这是可能的话,它是在C++内部还是在lua包装代码中完成的?任何示例代码都会很好。

编辑1:这是我的想法,我不确定它是否会起作用,或者是否足够快。

代码语言:javascript
复制
typedef struct luaelement
{
   int type;
   std::string name;
   void* addr; //newly added field
   bool isRef;  //newly added
} luaelement;

glbLuaElementSet=new set<luaelement,comparenocaseforluaelement>();

int l_newindex(lua_State* L)
{
    luaelement element;
    const char* key=lua_tostring(L,-2);
    string str=key;
    element.name=key;
    element.type=lua_type(L,-1);
    //How can I get the address, maybe a metamethod named address
    glbLuaElementSet->insert(element); 
    lua_rawset(L,1);
}

void l_registermetamethod(lua_State* L)
{
    lua_getglobal(L,"_G");
    lua_createtable(L, 0, 1);
    lua_pushcfunction(L, l_newindex);
    lua_setfield(L, -2, "__newindex");
    lua_setmetatable(L, -2);
}

现在,使用glbLuaElementSet变量和l_newindex元方法,我可以跟踪插入到全局_G表中的所有变量。我计划通过检查void*地址来实现并查看对已经存在的userdata变量的引用是否到位。我不知道这样做是否真的有效,在性能方面是否值得付出这么大的努力。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-05 02:03:40

但是,如何使A=B按值传递,以便B更改时不影响A。

你不能这么做。

记住: Lua是动态输入的。因此,虽然A和B现在恰好存储了矩阵类型,但是稍后使用A = 1是非常好的。现在,A存储一个整数。

C++和Lua是非常不同的语言。在C++中,变量要么是对象,要么是对象的引用(指针是指针类型的对象)。每个变量都只保存它开头的对象。可以更改存储在该对象中的值,但该对象本身存在,并且具有由所述变量的生存期定义的生存期。

在Lua中,变量只是一个可以存储对象的框。该框与它当前存储的对象没有关系;任何框都可以容纳任何对象。在任何时候,你都可以把盒子里的东西和其他盒子里的物体交换。

您不能干预将一个变量复制到另一个变量(通常情况下)。你可以做元体操,但这只适用于表中的成员。局部变量永远不会受到影响)。这就是卢阿作为一种语言的工作方式。C++变量是对象;Lua变量是存储框。最好接受不能用Lua编写C++样式的代码,而应该专注于用Lua编写Lua风格的代码。

因此,如果要创建对象的副本,则必须显式地创建该对象的副本。

这是我的想法,我不确定它是否会起作用,或者是否足够快。

由于几个原因,它将无法工作。

首先,将元可应用于全局表本身,这通常是.粗鲁。

其次,即使您的代码有效,它也不会适用于像这样简单的东西:

代码语言:javascript
复制
globalVar = {}  --Perfectly legal to set a table inside the global table.
globalVar.value = A
globalVar.value = B  --Will not alert your copying code.

__newindex元方法不是递归的。它不能在表的层次结构上来回走动。因此,存储在全局表中的表仍然可以更改其成员。

别再试图把Lua变成不一样的东西了。用你所拥有的语言,而不是你想要的语言。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35214952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档