Lua: 好的, 坏的, 和坑爹的
好的
小巧: 20000行C代码 可以编译进182K的可执行文件 (Linux下).
可移植: 只要是有ANSI C 编译器的平台都可以编译. 你可以看到它可以在几乎所有的平台上运行:从 microcontrollers Lego Minstorms NXT, 到 移动平台, 到 游戏主机,甚至 浏览器 (翻译成JavaScript). 作为一个嵌入式可扩展语言 提供了简单直接的 C/C++交互接口.
足够快:见 与其它语言的性能比较, 还有一个 JIT编译器可以显著地提高多数任务的性能; 对于那些仍然对性能不满意的人, 可以把关键部分使用C实现, 然后与其集成, 这样还可以享受其它方面的好处. Lua 从 Modula (Pascal的分支, 已经广泛应用于教育做为教学语言)借鉴了多数的控制语法. 我现在仍然记得早期使用过Philippe Kahn的快速而优雅的 Turbo Pascal IDE. 集成的解释器:只需要在命令行下运行 lua. 先天的协程支持, 用于实现 迭代器 和非抢占式多线程. 低延迟的增量垃圾回收, 没有额外的内存开销, 低实现复杂度, 并且支持 weak tables.
@1, 强大并多样化的表 可以保存任意类型的数据 (除了 nil) , 还可以使用任意类型的值进行索引 (除了 nil): {1, 2, 5, foo = "bar", [func] = "something", ["some spaces"] = value()}.
@2, 词法作用域. 一流的函数 和 闭包 支持的 函数式编程.
@3, 尾调用: return functioncall()
@4, 递归函数不需要事先声明: local function foo() ... foo() ... end; 注意这样不行 local foo = function() ... foo() ... end.
@5, 函数返回 多个值: return 1, 2, 3. 调用者可以认为返回值是任意个数的: 如果多于3个, 其余会被丢弃; 如果少于3个, 那其它的会是未初始化的 nil.
@6, 函数允许变化的变量个数, function foo(...) local args = {...}; bar(param, ...) end.
@7, Table可以 "拆包" 成参数列表,unpack (或 Lua 5.2的 table.unpack): print(unpack({1, 2, 3})) 打印1 2 3.
@8, 操作环境变量 (Lua 5.1中的getfenv 和setfenv 和Lua 5.2中的_ENV 操作), 此外还可以构造 沙盒 .
@9, 同时赋值多个变量: local a, b, c = 1, 2, x, y = y, x, or a, b = foo().
@10, 多行字符串 (using [[...]]; 可以使用 [[...[=[...]=]...]])包含和注释 (--[[...]]).
@11, 可选的分号语句分隔符 (多数用于解决模棱两可的的情况 a = f; (g).x(a)).
@12, 重载使用 metatables. 元编程 可以根据你的 DSL修改抽象语法树来创造新的语法.
@13, for 语句有两种形式: generic (使用迭代器: for a in iter() do ... end) 和 numeric (使用数字: for a = 1, 5, 0.1 do ... end); 数字的这个支持各种类型的步进 (不仅仅是整数).
@14, 函数调用的语法糖 (f'string', f"string", f[[string]], and f{table})和方法调用(obj:m()).
@15, 简单而强大的 调试 库. 与众不同的 表和字符串索引从1而不是0开始. 对一个表中的值赋 nil 会从表中删除它. 这就是说对于不存在的值返回 nil , 所以元素存不存在跟它是不是 nil是同一个问题. a = {b = nil} 产生一个空表.
@16, 没有独立的整数类型; 数字类型 表示的是实数.
@17, 没有类; 面向对象 使用 表 和 函数实现; 继承使用 metatable 机制实现. 方法调用使用 object:method(args) 的写法, 与 object.method(object, args) 的写法是等价的, 但 object 只取值一次.
@18, nil 和false 是仅有的表示假的值; 0, 0.0, "0" 等其它的一切值都是true. 不等于是 ~= (例如, if a ~= 1 then ... end).
@19, not, or, and 操作符是逻辑运算符. 赋值是语句, 这就意味着没有 a=b=1 或if (a=1) then ... end的写法.
@20, 没有 a+=1, a++, 或其它简写形式.
@21, 没有 continue 语句, 尽管有一个 解释 和一堆的替代品, 如在循环中使用 repeat break until true 跳出 或者使用一个Lua 5.2中的goto 语句. 没有 switch 语句.
@24, 某些上下文可能会用到括号; 例如, a = {}; a.field 正常, 但{}.field 不行; 后者需要这样写 ({}).field 注释(这样得到的值是哪里的?>>({})是个匿名地址).
@25, 循环的控制变量默认是局部的, 循环完了就没了. for 循环中的极限和步进值是 缓存过的; 这意味着 for i = init(), limit(), step() do ... end 中的三个函数 init, limit, 和step 只在循环开前调用过一次.
@26, 条件 和其它控制语言不需要括号.
@27, 字符串和数字会自动转换 (需要一个数字时提供一个字符串, 反之亦然), 除了相等比较: 0 == "0" 为false, {} ~= 1 为 true, 还有foo["0"] 和foo[0] 引用的是表中不同的值; 其它关系运算符会在比较不同类型的值时产生错误.
@28, 逗号和分号 都可以作为表中的元素分隔符; 也同样都可以作为 可选的分隔符 放在结束括号前: a = {a = 1, b = 2, }.
@29 比想像中还要少的内部组件; 可能一些人觉得这就像 "电池没有包含在内"一样. 从另一个角度来看, 这成就了它的紧凑而又可移植的核心, 不过同时有一些库可以进行补偿, 如 LuaRocks 和Penlight (之后可以去看看这个 ).
#1, 有限的错误处理支持 (使用pcall 和xpcall),尽管有些人 争论这已经够用了 , 只需要加一些语法糖和特性支持 (如确定性的finalizer). pcall 和error 的组合十分强大, 特别是 error 可以返回任何东西 (例如一个表)而不是仅仅是一个字符串, 但是 catch ... finally 结构在多数情况下可能更加清晰直观.
#5, 没有类/对象 finalizer. Lua 通过 __gc metamethod提供finalizer 的功能 , 但它只能用于自定义类型 (不是表), 并且不能跟其它语言的相应功能匹配, 举例来说, Perl中的 DESTROY 和 END方法. [05/27/2012更新] Lua 5.1中有一个没有文档说明的 newproxy特性, 它实现了表的 finalizers; Lua 5.2 移除了这个特性的同时增加了 表的__gc元方法.
#6, 没有Lua和C代码之间的yielding: coroutine.yield ()在跨越 Lua/C 边界调用时会失败 attempt to yield across metamethod/C-call boundary. 我在使用 luasocket和协程进行异步编辑时多次遇到过这个错误, 最后使用 copas 模块解决. 在Lua 5.2中这个问题得到解决.
&1, 表中元素的个数并不是很容易获取, 结果取决于你怎么做 (或你怎么定义"长度"). 这可能不是个意外, 因为Lua提供了强大的表并支持灵活的索引方式 (数字或其它Lua类型, 除了 nil).
Lua: 好的, 坏的, 和坑爹的的更多相关文章
- 理解 Lua 的那些坑爹特性
按:最近看到了依云的文章,一方面,为Lua被人误解而感到十分难过,另一方面,也为我的好友, 依云没有能够体会到Lua的绝妙和优雅之处而感到很遗憾,因此我写了这篇文章,逐条款地说明了 依云理解中出现的一 ...
- 游戏人生(一),我的lua之旅:那些坑爹的CCBReaderLoad
首先,我们说说这个CCBReaderLoad. 这个脚本是cocos2dx自带的一个lua+cocosbuilder 的工具,详细功能呐,往下看. 先来看下我遇到的一个问题: ----美工给了我一个. ...
- JS魔法堂:被玩坏的innerHTML、innerText、textContent和value属性
一.前言 由于innerText并非W3C标准属性,因此我们无法在FireFox中使用它(修正:FF45+已经支持innerText属性),一般情况下我们可以使用textContent来代替,但它两者 ...
- 一键自动发布ipa(更新svn,拷贝资源,压缩资源,加密图片资源,加密数据文件,加密lua脚本,编译代码,ipa签名,上传ftp)
一键自动发布ipa(更新svn,拷贝资源,压缩资源,加密图片资源,加密数据文件,加密lua脚本,编译代码,ipa签名,上传ftp) 程序员的生活要一切自动化,更要幸福^_^. 转载请注明出处http: ...
- lua table remove元素的问题
当我在工作中使用lua进行开发时,发现在lua中有4种方式遍历一个table,当然,从本质上来说其实都一样,只是形式不同,这四种方式分别是: for key, value in pairs(tbtes ...
- nginx + lua 构建网站防护waf(一)
最近在帮朋友维护一个站点.这个站点是一个Php网站.坑爹的是用IIS做代理.出了无数问题之后忍无可忍,于是要我帮他切换到nginx上面,前期被不断的扫描和CC.最后找到了waf这样一个解决方案缓解一下 ...
- 在JAVA中使用LUA脚本记,javaj调用lua脚本的函数(转)
最近在做一些奇怪的东西,需要Java应用能够接受用户提交的脚本并执行,网络部分我选择了NanoHTTPD提供基本的HTTP服务器支持,并在Java能承载的许多脚本语言中选择了很久,比如Rhino,Jy ...
- 【精选】Nginx模块Lua-Nginx-Module学习笔记(一)Nginx Lua API 接口详解
源码地址:https://github.com/Tinywan/Lua-Nginx-Redis 一.介绍 各种* _by_lua,* _by_lua_block和* _by_lua_file配置指令用 ...
- linux下编译make文件报错“/bin/bash^M: 坏的解释器,使用grep快速定位代码位置
一.linux下编译make文件报错“/bin/bash^M: 坏的解释器 参考文章:http://blog.csdn.net/liuqiyao_01/article/details/41542101 ...
随机推荐
- 16.iOS APP图标和启动画面尺寸
1. 桌面图标 (app icon) for iPhone6 plus(@3x) : 180 x 180 for iPhone 6/5s/5/4s/4(@2x) : 120 x 120 2. 系统搜索 ...
- load与initialize
NSObject类有两种初始化方式load和initialize load + (void)load; 对于加入运行期系统的类及分类,必定会调用此方法,且仅调用一次. iOS会在应用程序启动的时候调用 ...
- Samba网络配置
Samba网络配置 操作环境 ubuntu14.04 1. 更新Linux源列表 sudo apt-get update 2. 安装Samba服务 sudo apt-get install samba ...
- 启动tomcat时遇到的问题
1.当启动Tomcat时,出现了如下信息: The APR based Apache Tomcat Native library which allows optimal performance in ...
- C# JS 单例
单例模式的三个特点: 1,该类只有一个实例 2,该类自行创建该实例(在该类内部创建自身的实例对象) 3,向整个系统公开这个实例接口 模式1: class Singleton { //私有,静态的类自身 ...
- 我与solr(四)--solrJ
SolrJ索引库: solr提供的一个客户端操作框架,在文件/solr6.2/dist下面可以找到该jar包solrj.jar以及相关jar包,可以使用maven添加. java使用solrJ如下: ...
- 写在学AngularJS之前
近来从不同途径听说AngularJS和MEAN stack,感觉很有趣的样子,于是准备抽时间来学习一下.在这里记录学习过程中的笔记. 简单整理一下先: 1. 我的学习资料: a) 官网 b) wiki ...
- 特征哈希(Feature Hashing)
[本文链接:http://www.cnblogs.com/breezedeus/p/4114686.html,转载请注明出处] 我的博客主营地迁至github,欢迎朋友们有空去看看:http://br ...
- Pair Project:电梯控制程序
12061160刘垚鹏 & 12061166宋天舒 1.1结对编程的优缺点结对编程相对于个人编程有很多优点.首先,督促作用,在讨论过程中能够很快投入工作,为了不耽误对方时间,我们会尽快完成各自 ...
- linux-9基本命令之-wget
1.wget 命令用于下载网络文件,格式:"wget[参数] 下载地址" wget 参数 -b 后台下载模式 -O 下载到指定的目录 -t 最大尝试次数 -p 下载页面内所有的资源 ...