Lua 比 C/C++ 更适合的示例用法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/940896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Example usage where Lua fits much better than C/C++
提问by bugmenot77
I'm currently embedding Lua and using it as a glorified intelligent config file. However, I think I'm missing something since people rave about the uses of Lua.
我目前正在嵌入 Lua 并将其用作美化的智能配置文件。但是,我想我错过了一些东西,因为人们对 Lua 的使用赞不绝口。
For example, I can easily explain why you might use shell scripting instead of C by showing this example (admittedly , boost regexp is overkill):
例如,通过展示这个例子,我可以很容易地解释为什么你可以使用 shell 脚本而不是 C(诚然,boost regexp 是矫枉过正):
#include <dirent.h>
#include <stdio.h>
#include <boost/regex.hpp>
int main(int argc, char * argv[]) {
DIR *d;
struct dirent *dir;
boost::regex re(".*\.cpp$");
if (argc==2) d = opendir(argv[1]); else d = opendir(".");
if (d) {
while ((dir = readdir(d)) != NULL) {
if (boost::regex_match(dir->d_name, re)) printf("%s\n", dir->d_name);
}
closedir(d);
}
return(0);
and compare it to:
并将其与:
for foo in *.cpp; do echo $foo; done;
Are there any examples that you can give in Lua which can make it 'click' for me?
有没有你可以在 Lua 中给出的例子,可以让它为我“点击”?
EDIT: Maybe my problem is that I don't know Lua well enough yet to use it fluently as I'm finding it easier to write C code.
编辑:也许我的问题是我对 Lua 还不够了解,无法流利地使用它,因为我发现编写 C 代码更容易。
EDIT2:
编辑2:
One example is a toy factorial program in C++ and Lua:
一个例子是一个用 C++ 和 Lua 编写的玩具阶乘程序:
#include <iostream>
int fact (int n){
if (n==0) return 1; else
return (n*fact(n-1));
}
int main (){
int input;
using namespace std;
cout << "Enter a number: " ;
cin >> input;
cout << "factorial: " << fact(input) << endl;
return 0;
}
Lua:
路亚:
function fact (n)
if n==0 then
return 1
else
return n * (fact(n-1))
end
end
print ("enter a number")
a = io.read("*number")
print ("Factorial: ",fact(a))
Here, the programs look alike, but there's clearly some cruft in the include, namespace and main() declarations you can get rid of. Also remove variable declarations and strong typing.
在这里,程序看起来很相似,但在 include、namespace 和 main() 声明中显然有一些你可以摆脱的细节。还删除变量声明和强类型。
Now are people saying this is the advantage which adds up over a larger program, or is there more to it? This doesn't stand out in the same way as the bash example.
现在人们是说这是相对于更大程序的优势,还是有更多优势?这与 bash 示例不同。
回答by Reed Copsey
Using a scripting language such as Lua has many other benefits.
使用诸如 Lua 之类的脚本语言还有许多其他好处。
A couple of advantages to Lua vs. C++:
Lua 与 C++ 的几个优势:
- It's often shorter in terms of development time due to the high-level nature, as in your example.
- It doesn't require recompilation to change behavior.
- Behavior can be changed on non-development machines.
- Prototyping is very fast and easy, since you can just tweak logic at runtime.
- 由于高级性质,它在开发时间方面通常更短,如您的示例所示。
- 它不需要重新编译来改变行为。
- 可以在非开发机器上更改行为。
- 原型制作非常快速和容易,因为您可以在运行时调整逻辑。
回答by RBerteig
Scripting languages reduce the effort required to build complex GUIs that otherwise require a lot of framework glue and repetition of code. Several GUI toolkits are available with Lua bindings, including wxWidgetsand the IUP toolkit.
脚本语言减少了构建复杂 GUI 所需的工作量,否则这些 GUI 需要大量框架粘合和代码重复。Lua 绑定提供了几个 GUI 工具包,包括wxWidgets和IUP 工具包。
In both of those bindings, first class function values and full closures make event callbacks easy to code and easy to use.
在这两个绑定中,一流的函数值和完整的闭包使事件回调易于编码和使用。
A large application using Lua at its core (such as Adobe Photoshop Lightroom) has an outer C/C++ program that hosts the Lua interpreter and provides access to its core features by registering C functions with that interpreter. It typically implements compute-intensive core functions in C functions, but leaves the overall flow, operation, and even the GUI layout to Lua scripts.
以 Lua 为核心的大型应用程序(例如 Adobe Photoshop Lightroom)有一个外部 C/C++ 程序,该程序承载 Lua 解释器,并通过向该解释器注册 C 函数来提供对其核心功能的访问。它通常在 C 函数中实现计算密集型核心功能,但将整体流程、操作甚至 GUI 布局留给 Lua 脚本。
I have found in my own projects that it is often the case that the stock standalone Lua interpreter (lua.exe or wlua.exe) is sufficient for the outer application when combined with IUP loaded at run time along with one or two custom DLL-based Lua modules coded in C that implement features that require that level of performance, or features that are implemented via other C-callable libraries.
我在我自己的项目中发现,通常情况下,当与运行时加载的 IUP 以及一两个自定义 DLL 结合使用时,库存的独立 Lua 解释器(lua.exe 或 wlua.exe)足以满足外部应用程序的需求。基于用 C 编码的 Lua 模块,实现需要该级别性能的功能,或通过其他 C 可调用库实现的功能。
The important points for my projects have included:
我的项目的要点包括:
- True tail calls allow for a easy expression of finite state machines.
- Garbage collected memory management.
- Anonymous functions, closures, first class function values.
- Hash tables.
- Rich enough string library.
- Userdata extends the garbage collector to C side allocations.
- Metatables allow a rich variety of object oriented and functional techniques.
- Small but sufficiently powerful C API.
- Good documentation, with open source as a backup.
- Good user to user support through the mailing listand wiki.
- Powerful modules such as a PEGparser available from the authors and from the community.
- 真正的尾调用可以轻松表达有限状态机。
- 垃圾收集内存管理。
- 匿名函数、闭包、一等函数值。
- 哈希表。
- 足够丰富的字符串库。
- Userdata 将垃圾收集器扩展到 C 端分配。
- 元表允许丰富多样的面向对象和功能技术。
- 小但足够强大的 C API。
- 良好的文档,以开源作为备份。
- 通过邮件列表和wiki为用户提供良好的用户支持。
- 强大的模块,例如作者和社区提供的PEG解析器。
One of my favorite examples to cite is a test jig I built for an embedded system that required about 1000 lines of Lua and 1000 lines of C, ran under lua.exe, and used IUP to present a full Windows GUI. The first version was running in about a day. In C++ with MFC, it would have been at least a week's work, and many thousands of lines of code.
我最喜欢引用的示例之一是我为嵌入式系统构建的测试夹具,该系统需要大约 1000 行 Lua 和 1000 行 C,在 lua.exe 下运行,并使用 IUP 来呈现完整的 Windows GUI。第一个版本运行了大约一天。在带有 MFC 的 C++ 中,至少需要一周的工作和数千行代码。
回答by 0x6adb015
Try to implement a Lua table in C/C++, you'll see the strength of Lua right there.
尝试用 C/C++ 实现一个 Lua 表,你就会看到 Lua 的强大之处。
In Lua:
在卢阿:
a["index"] = "value"
In C, start by reading about linked list...
在 C 中,从阅读链表开始......
C++ STL may help, but it is going to be a lot more verbose than Lua.
C++ STL 可能会有所帮助,但它会比 Lua 冗长得多。
Also, Lua makes great glue. It is so easy (IMHO) to interface to C.
另外,Lua 是很好的胶水。与 C 接口非常容易(恕我直言)。
回答by Kosi2801
I don't know if I make it 'click' for you but I'll try.
我不知道我是否让它为你“点击”,但我会尝试。
One of the advantages of embedding Lua is, that you can not only use it as a configfile but actually offer your C/C++-interfaces to lua and 'script' their usage via the Lua-scripting language.
嵌入 Lua 的优点之一是,您不仅可以将其用作配置文件,还可以实际为 lua 提供 C/C++ 接口,并通过 Lua 脚本语言“编写”它们的使用。
If you want to change the behaviour/logic of your application, you just have to change the code in the Lua-script without the need to recompile the whole application.
如果您想更改应用程序的行为/逻辑,您只需更改 Lua 脚本中的代码,而无需重新编译整个应用程序。
Prominent uses are game logics like AI oder state machines, where a fast roundtrip-time from change to play is essential for developing the game.
突出的用途是游戏逻辑,如 AI 或状态机,其中从更改到播放的快速往返时间对于开发游戏至关重要。
Of course, the main logic has then to be present within the Lua-script, not within the C/C++-code, to be effectively used.
当然,主要逻辑必须存在于 Lua 脚本中,而不是存在于 C/C++ 代码中,才能有效使用。
回答by none
Programming just in C can be a very tedious and redundant task, this certainly applies when compared to more abstract, high level languages.
仅用 C 编程可能是一项非常乏味和冗余的任务,与更抽象的高级语言相比,这当然适用。
In this sense, you can get started and finish things much more quickly than doing everything directly in C, this is because many things that need to be set up, done and cleaned up explicitly and manually in C, are often implicitly and automatically handled by a scripting language such as Lua (e.g. imagine memory management).
从这个意义上说,与直接在 C 中完成所有事情相比,您可以更快地开始和完成事情,这是因为许多需要在 C 中显式和手动设置、完成和清理的事情通常由 C 语言隐式和自动处理一种脚本语言,如 Lua(例如想象内存管理)。
Similarly, many more abstract data structures and algorithms are often directly provided by such high level languages, so you don't have to re-invent the wheel and re-implement it, if all you need is a standard container (think linked list, tree, map etc).
类似地,许多更抽象的数据结构和算法通常由此类高级语言直接提供,因此您不必重新发明轮子并重新实现它,如果您只需要一个标准容器(想想链表,树、地图等)。
So, you can get a fairly good ROI when using a fairly abstract scripting language such as Lua or even Python, especially if the corresponding language comes with a good library of core functionality.
因此,当使用相当抽象的脚本语言(例如 Lua 甚至 Python)时,您可以获得相当不错的 ROI,尤其是如果相应的语言带有良好的核心功能库。
So, scripting is actually ideal in order to prototype ideas and projects, because that's when you need to be able to concentrate on your effort, rather than all the mechanical redundancies that are likely to be identical for most projects.
因此,脚本编写实际上是对想法和项目进行原型设计的理想选择,因为那时您需要能够专注于自己的努力,而不是大多数项目可能都相同的所有机械冗余。
Once you got a basic prototype done, you can always see how to improve and optimize it further, possibly be re-implementing essential key functionality in C space, in order to improve runtime performance.
一旦你完成了一个基本的原型,你总是可以看到如何进一步改进和优化它,可能是在 C 空间中重新实现基本的关键功能,以提高运行时性能。
回答by Jakub M.
LUA has closures, and closures rock. For example:
function newCounter ()
local i = 0
return function () -- anonymous function
i = i + 1
return i
end
end
c1 = newCounter()
print(c1()) --> 1
print(c1()) --> 2
You can create a function and pass it around. Sometimes it is more handy than creating separate class and instantiate it.
您可以创建一个函数并将其传递。有时它比创建单独的类并实例化它更方便。
回答by Norman Ramsey
The main advantages of Lua as a programming language (apart from the embeddability) are
Lua 作为编程语言的主要优点(除了可嵌入性)是
- Powerful, efficient hash table as the main data structure
- String-processing library with an excellent balance of complexity and expressive power
- First-class functions and generic
for
loop - Automatic memory management!!
- 强大、高效的哈希表为主要数据结构
- 字符串处理库,在复杂性和表现力之间取得了极好的平衡
- 一等函数和泛型
for
循环 - 自动内存管理!!
It's hard to find a short example that illustrates all these. I have 191 Lua scripts in my ~/bin
directory; here's one that takes the output of pstotext
and joins up lines that end in a hyphen:
很难找到一个简短的例子来说明所有这些。我的~/bin
目录中有 191 个 Lua 脚本;这是一个获取输出pstotext
并连接以连字符结尾的行:
local function printf(...) return io.stdout:write(string.format(...)) end
local function eprintf(...) return io.stderr:write(string.format(...)) end
local strfind, strlen = string.find, string.len
function joined_lines(f)
return coroutine.wrap(function()
local s = ''
for l in f:lines() do
s = s .. l
local n = strlen(s)
if strfind(s, '[%-3]$', n-1) then
s = string.sub(s, 1, n-1)
else
coroutine.yield(s)
s = ''
end
end
end)
end
-- printf('hyphen is %q; index is %d\n', '-', string.byte('-'))
for _, f in ipairs(arg) do
for l in joined_lines(io.popen('pstotext ' .. f, 'r')) do
printf('%s\n', l)
end
end
This example shows several features to advantage but does nothing interesting with tables.
这个例子展示了几个有利的特性,但对表格没有任何有趣的作用。
Here's a short snippet from a Key Word In Context indexing program, which fetches context from a table and formats the key word in context. This example makes more extensive use of nested functions and shows some more table and string stuff:
这是上下文中关键字索引程序的一个简短片段,该程序从表中获取上下文并在上下文中格式化关键字。这个例子更广泛地使用了嵌套函数,并显示了更多的表和字符串内容:
local function showpos(word, pos, lw, start)
-- word is the key word in which the search string occurs
-- pos is its position in the document
-- lw is the width of the context around the word
-- start is the position of the search string within the word
local shift = (start or 1) - 1 -- number of cols to shift word to align keys
lw = lw - shift -- 'left width'
local rw = cols - 20 - 3 - lw - string.len(words[pos]) -- right width
local data = assert(map:lookup(pos)[1], "no map info for position")
-- data == source of this word
local function range(lo, hi)
-- return words in the range lo..hi, but only in the current section
if lo < data.lo then lo = data.lo end
if hi > data.hi then hi = data.hi end
local t = { }
for i = lo, hi-1 do table.insert(t, words[i]) end
return table.concat(t, ' ')
end
-- grab words on left and right,
-- then format and print as many as we have room for
local left = range(pos-width, pos)
local right = range(pos+1, pos+1+width)
local fmt = string.format('[%%-18.18s] %%%d.%ds %%s %%-%d.%ds\n',
lw, lw, rw, rw)
printf(fmt, data.title, string.sub(left, -lw), word, right)
end
回答by Freelancer Epic
I use a game engine called Love2D which uses Lua for writing games. All the system calls and heavy-lifting is done in a C program which reads a Lua script.
我使用名为 Love2D 的游戏引擎,它使用 Lua 编写游戏。所有的系统调用和繁重的工作都是在一个读取 Lua 脚本的 C 程序中完成的。
Writing a game in C or C++, you find yourself trying to work with the subtleties of the system rather than just implementing your ideas.
用 C 或 C++ 编写游戏,您会发现自己正在尝试处理系统的微妙之处,而不仅仅是实现您的想法。
Lua allows for "clean" dirty-style coding.
Lua 允许“干净”的脏式编码。
Here's an example of a game object written in pure lua:
下面是一个用纯 lua 编写的游戏对象的例子:
local GameObj = {} -- {} is an empty table
GameObj.position = {x=0,y=0}
GameObj.components = {}
function GameObject:update()
for i,v in ipairs(self.components) do -- For each component...
v:update(self) -- call the update method
end
end
To instantiate:
实例化:
myObj = setmetatable({},{__index=GameObj})
-- tables can have a meta table which define certain behaviours
-- __index defines a table that is referred to when the table
-- itself doesn't have the requested index
Let's define a component, how about keyboard control? Assuming we have an object that does input for us (that would be supplied C-side)
让我们定义一个组件,键盘控制怎么样?假设我们有一个为我们做输入的对象(将在 C 端提供)
KeyBoardControl = {}
function KeyBoardControl:update(caller)
-- assuming "Input", an object that has a isKeyDown function that returns
-- a boolean
if Input.isKeyDown("left") then
caller.position.x = caller.position.x-1
end
if Input.isKeyDown("right") then
caller.position.x = caller.position.x+1
end
if Input.isKeyDown("up") then
caller.position.y = caller.position.y-1
end
if Input.isKeyDown("down") then
caller.position.y = caller.position.y+1
end
end
--Instantiate a new KeyboardControl and add it to our components
table.insert(myObj.components,setmetatable({},{__index=KeyboardControl})
Now when we call myObj:update() it will check inputs and move it
现在,当我们调用 myObj:update() 时,它将检查输入并移动它
Let's say we'll be using plenty of this kind of GameObj with a KeyboardControl, we can instantiate a prototype KeyObj and use THAT like an inherited object:
假设我们将使用大量这种带有 KeyboardControl 的 GameObj,我们可以实例化一个原型 KeyObj 并像继承对象一样使用 THAT:
KeyObj = setmetatable( {}, {__index = GameObj} )
table.insert(KeyObj.components,setmetatable( {}, {__index = KeyboardControl} )
myKeyObjs = {}
for i=1,10 do
myKeyObjs[i] = setmetatable( {}, {__index = KeyObj} )
end
Now we have a table of KeyObj that we can play with. Here we can see how Lua provides us with a powerful, easy to extend, flexible object system which allows us to structure our program in accordance with the problem we're trying to solve, rather than having to bend the problem to fit into our language.
现在我们有了一个可以玩的 KeyObj 表。在这里我们可以看到 Lua 如何为我们提供了一个强大的、易于扩展的、灵活的对象系统,它允许我们根据我们试图解决的问题来构建我们的程序,而不是必须改变问题以适应我们的语言.
Also, Lua has some nice other features like functions as first-class types, allowing for lambda programming, anonymous functions, and other stuff that usually has comp-sci teachers smiling creepily.
此外,Lua 还有一些不错的其他特性,比如函数作为一流类型,允许 lambda 编程、匿名函数和其他通常让 comp-sci 老师毛骨悚然地微笑的东西。
回答by Jared
For an example of where Lua fits better then c++ look at distributing scripts. Mush Clientoffers Lua as a scripting language. As shown by the link above you can do a lot with Lua to extend the program. Unlike C++ though Lua doesn't have to be compiled and can be restricted. For example you can sandbox Lua so it can't access the file system. This means that if you get a script from someone else it is incapable of destroying your data since it can't write to the disk.
有关 Lua 比 c++ 更适合的示例,请查看分发脚本。Mush Client提供 Lua 作为脚本语言。如上面的链接所示,您可以使用 Lua 做很多事情来扩展程序。与 C++ 不同,虽然 Lua 不需要编译并且可以被限制。例如,您可以对 Lua 进行沙箱处理,使其无法访问文件系统。这意味着如果您从其他人那里获得脚本,它就无法破坏您的数据,因为它无法写入磁盘。