理解 Lua 的那些坑爹特性
1. 协程只能在Lua代码中使用
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
c = require('c') co = coroutine.create(function() print('coroutine yielding') c.callback(function() coroutine.yield() end) print('coroutine resumed') end) coroutine.resume(co) coroutine.resume(co) print('the end') |
|
1
|
local c = require 'c' |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#include<stdio.h> #include<stdlib.h> #include<lua.h> #include<lualib.h> #include<lauxlib.h> static int c_callback(lua_State *L){ int ret = lua_pcall(L, 0, 0, 0); if(ret){ fprintf(stderr, "Error: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); exit(1); } return 0; } static const luaL_Reg c[] = { {"callback", c_callback}, {NULL, NULL} }; LUALIB_API int luaopen_c (lua_State *L) { luaL_register(L, "c", c); return 1; } |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
#include<stdio.h> #include<stdlib.h> #define LUA_LIB /* 告诉Lua,这是一个LIB文件 */ #include<lua.h> #include<lualib.h> #include<lauxlib.h> static int c_cont(lua_State *L) { /* 这里什么都不用做:因为你的原函数里面就没做什么 */ return 0; } static int c_callback(lua_State *L){ /* 使用 lua_pcallk,而不是lua_pcall */ int ret = lua_pcallk(L, 0, 0, 0, 0, c_cont); if(ret) { fprintf(stderr, "Error: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); exit(1); } /* 因为你这里什么都没做,所以c_cont里面才什么都没有。如果这里需要做 * 什么东西,将所有内容挪到c_cont里面去,然后在这里简单地调用 * return c_cont(L); * 即可。 */ return 0; } static const luaL_Reg c[] = { {"callback", c_callback}, {NULL, NULL} }; LUALIB_API int luaopen_c (lua_State *L) { /* 使用新的 luaL_newlib 函数 */ luaL_newlib(L, c); return 1; } |
|
1
2
3
4
|
lua -- co.lua coroutine yieldingcoroutine resumed the end |
|
1
2
3
4
5
6
7
8
9
|
function do_login(server) server:login(function(data) -- 错误处理先不管,假设有一个全局处理错误的机制(后面会提到,实际 -- 上就是newtry/protect机制) server:get_player_info(function(data) player:move_to(data.x, data.y) end) end, "username", "password") end |
|
1
2
3
4
5
|
function d_login(server) server:login("username", "password") local data = server:get_player_info() player:move_to(data.x, data.y) end |
|
1
2
3
4
5
6
7
8
9
10
11
|
local current function server:login(name, password) assert(not current, "already send login message!") server:callback_login(function(data) local cur = current current = nil coroutine.resume(cur, data) end, name, password) current = coroutine.running() coroutine.yield() end |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
function coroutinize(f, reenter_errmsg) local current return function(...) assert(not current, reenter_errmsg) f(function(...) local cur = current current = nil coroutine.resume(cur, ...) end, ...) current = coroutine.running() coroutine.yield() end end |
2. 幽灵一般的 nil
|
1
2
3
4
5
6
7
|
undefined = {} -- 指定一个全局变量存在,但不指向任何地方:a = undefined -- 判断这个全局变量是否不指向任何地方: if a == undefine then ... end -- 彻底删除这个变量: a = nil |
3. 没有continue
|
1
2
|
local a = true repeat a = false until a |
|
1
2
3
4
5
6
7
|
for line in configfile do if string.sub(line, 1, 1) == '#' then goto next end parse_config(line) ::next:: end |
|
1
2
3
4
5
6
7
8
9
10
|
local i repeat if i == 5 then goto next end local j = i * i print("i = "..i..", j = "..j) i = i + 1 ::next:: until i == 10 |
|
1
2
3
4
|
lua -- "noname\2013-01-03-1.lua" lua: noname\2013-01-03-1.lua:10: <goto next> at line 4 jumps into the scope of local 'j'shell returned 1 Hit any key to close this window... |
4. 错误信息的表达
5. 下标
6. 提前返回
7. 方法调用
8. 面向对象
9. 结论
理解 Lua 的那些坑爹特性的更多相关文章
- 【转载】【游戏开发】在Lua中实现面向对象特性——模拟类、继承、多态
[游戏开发]在Lua中实现面向对象特性——模拟类.继承.多态 阅读目录 一.简介 二.前提知识 三.Lua中实现类.继承.多态 四.总结 回到顶部 一.简介 Lua是一门非常强大.非常灵活的脚本语 ...
- 理解Javascript的动态语言特性
原文:理解Javascript的动态语言特性 理解Javascript的动态语言特性 Javascript是一种解释性语言,而并非编译性,它不能编译成二进制文件. 理解动态执行与闭包的概念 动态执行: ...
- 【游戏开发】在Lua中实现面向对象特性——模拟类、继承、多态
一.简介 Lua是一门非常强大.非常灵活的脚本语言,自它从发明以来,无数的游戏使用了Lua作为开发语言.但是作为一款脚本语言,Lua也有着自己的不足,那就是它本身并没有提供面向对象的特性,而游戏开发是 ...
- 两个函数彻底理解Lua中的闭包
本文通过两个函数彻底搞懂Lua中的闭包,相信看完这两个函数,应该能理解什么是Lua闭包.废话不多说,上 code: --[[************************************** ...
- 深入理解Lua的闭包一:概念、应用和实现原理
本文首先通过具体的例子讲解了Lua中闭包的概念,然后总结了闭包的应用场合,最后探讨了Lua中闭包的实现原理. 闭包的概念 在Lua中,闭包(closure)是由一个函数和该函数会访问到的非局部变量 ...
- 理解lua中 . : self
前言 在LUA中,经常可以看到:. self,如果你学习过Java或C#语言,可以这样理解 .对于c#和java的静态方法 :相当于是实例方法 今天在CSDN上看到一篇博客写的很清楚,转载过来 原文出 ...
- lua table integer index 特性
table.maxn (table) Returns the largest positive numerical index of the given table, or zero if the t ...
- lua语言三则特性
pack和unpack 对于一个函数, 要将其入参转换为一个表, 则pack函数合适. 对于一个表要将其转换为 一个函数的入参, 则 lua原生提供的 unpack函数可以实现. do arrayDa ...
- 理解lua 语言中的点、冒号与self
转载自: http://blog.csdn.net/wangbin_jxust/article/details/12170233 lua编程中,经常遇到函数的定义和调用,有时候用点号调用,有时候用冒号 ...
随机推荐
- Linux系统目录结构
Linux系统目录结构图 目录:/ 是Linux的根目录 每个文件和目录从根目录开始,只有root用户具有该目录下的写权限: /root是root用户的主目录,这与 / 目录不一样: 目录:/bin ...
- 动态加载js文件
由于最近在弄echarts,关于地图类的效果,但是全国地图整体的js文件太大了,加载很耗费资源,所以要根据不同省份加载不同地区的js地图, 于是就想的比较简单, var script = docume ...
- Sass的学习
第一章:Sass简介 一. 什么是CSS预处理器 定义:CSS预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为CSS增加一些编程的特性,将CSS作为目标生成文件,然后开发者就只要使用 ...
- UVaLive 7143 Room Assignment (组合数+DP)
题意:有 n 个客人,m个房间,每个房间可住ci个人,这 n 个人中有 t 对双胞胎,sum{ci} = n 问你有多少种住房方法. 析:计数DP,dp[i][j] 表示前 i 个房间,还剩下 j ...
- VS2010 网页错误
VS2010向导添加消息处理时,弹出以上错误,原因之一为: 类内没有定义IDD的宏
- linux修改主机名的方法
linux修改主机名的方法 用hostname命令可以临时修改机器名,但机器重新启动之后就会恢复原来的值. #hostname //查看机器名#hostname -i //查看本机器名对应的ip ...
- 比较C++和C#的一个性能问题
C++:只要你的代码正确,算法良好,你比较少关注性能问题,编译器会替你搞定绝大部分工作 C#:你的代码正确,算法良好,你还得用工具去分析优化性能,JIT为了快速工作,很多优化工作没有深入开展. 手工优 ...
- angular下拉
<div class="form-group col-sm-4"> <label class="col-sm-5 control-label" ...
- hdu 3065 AC自动机
// hdu 3065 AC自动机 // // 题目大意: // // 给你n个短串,然后给你一个长串,问:各个短串在长串中,出现了多少次 // // 解题思路: // // AC自动机,插入,构建, ...
- 用cookie记住用户名
有时候,我们在做登陆框时会有个复选框选择请记住我,或者有时候会遇到一些弹出框说下次不再提醒,此功能我们可以用js中的cookie实现此功能 下面记录一下如何实现该功能: 利用cookie记录用户名 1 ...