【问题标题】:Emulating c++ 'using namespace' via _ENV通过_ENV模拟c ++'使用命名空间'
【发布时间】:2017-11-12 22:13:29
【问题描述】:

如果我有文件foo.lua:

local foo = {}
foo.add = function(a, b) return a+b end
foo.sub = function(a, b) return a-b end
foo.multiply = function(a, b) return a*b end
return foo

bar.lua 中,我大量使用来自foo.lua 的代码,我一直对输入foo.add() 感到困扰,宁愿在add() 中只写add() bar.lua 我可以添加以下内容:

local foo = require('foo')
local add, sub, multiply = foo.add, foo.sub, foo.multiply

但是当您在许多文件中包含许多值的别名时,这开始变得很痛苦。在 c++ 中有一种解决方法:

#include <iostream>
using namespace std

在 lua 中,我认为您可以像这样模拟此功能:

local foo = require('foo')
setmetatable(_ENV, {__index = foo})

据我所知,它尊重范围,所以像下面的代码这样的东西很好玩:

实际上下面的代码不起作用。我正在通过 lua repl 运行代码。当我在 lua 文件中编写下面的代码 sn-p 时,它没有给出想要的结果。

f = function() -- returns 2
    setmetatable(_ENV, {__index = foo})
    return add(1, 1)
end 
add(1, 1) -- returns 2

我有什么理由会后悔这样做吗? (除了同样适用于using namespace 的原因)

【问题讨论】:

  • 以这种方式使用 C++ 越来越被认为是不好的做法。
  • 我知道它在 c++ 中不受欢迎的一系列原因,但我不知道,在得到对该线程的响应后,我开始将它放在我的 lua 代码中。我倾向于避免编写需要高级知识才能在可能的情况下理解的代码,因为这会降低代码的可读性,而这显然违反了该规则。我只是好奇。

标签: lua metatable lua-5.2 meta-method lua-5.3


【解决方案1】:

改变全局环境对其他库不礼貌。

换一种方式试试:

do
  local _ENV = setmetatable(foo, {index = _ENV})
  print(add(1, 1))
end

请注意,add 将在 fooprint 中解析为原始 _ENV

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-08
    • 2014-07-17
    • 2012-12-15
    • 2013-11-16
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多