lua笔记

lua

先按照官网安装好lua解释器, 下载源码编译也很简单,下载地址:http://www.lua.org/download.html

lua类型

lua是动态类型语言,变量无须定义

Numbers:

包括整数,无精度限制整数,单精度浮点数,双精度浮点数,复数

>a = 1
>b = a*10
>print(b)
>c = 0.7
>print(c)

字符和数字转换:

> = tonumber("123") + 25
> = tonumber("123.456e5")

Strings:

>print("hello")
>who = 'lua user' -- 字符串可以使用"或' 多行用[[ ]]
>print(who)
>print("hello " .. who)  -- 拼接字符串使用 .. 而不是 +

Boolean:

>x = true
>print(not x)
>print(1 == 0)
>print(true ~= false)

Tables:

table是一种集合数据类型,集合数据类型用以存放collection(如list, set, arrays和联合数组<associative arrays>), collection包含其他对象(包括numbers, strings, 甚至是集合).

>x = {} -- empty table
>print(x)

更多table信息见后面

Functions:

如很多动态语言,函数可以赋值给变量

>foo = function() print("hello") end
>foo() -- call function
>print(foo)

function也可以放入tables

> a = "aeiou" -- a string
> b = 13      -- a number
> c = function()  -- a function
>  print ("\n\n\tAin't it grand")
> end
> d = { a, b ,c} -- put them in a table
> function printit(tata)  -- print their types.
> table.unpack(tata) -- unpack the table
> for key, value in ipairs(tata) do print(key, type(value)) end
> end
> printit(d)
1       string
2       number
3       function

nil values:

>print(x) --x is not defined before
nil
>t = nil
>print(t)

Userdata:

Userdata变量是lua外部的对象,比如在C中实现的对象。

Thread:

一个thread代表独立的执行线程

Querying type:

lua是反射语言,可以通过type得到变量类型

>x = '123'
>print(x, type(x))

Tables

>t = {}
>t['foo'] = 123
>t[3] = 'bar'
> = t[3] -- return t[3]
>t[3] = nil -- earse a key/value
>f = function() end
>t[f] = 456 --任何值都可以作为key,除了nil和NAN(not a number)
>t.bar = 789
>= t['bar']

--另一种添加key/value的方法
> t = {["foo"] = "bar", [123] = 456}
> = t.foo
bar
> = t[123]
456

--或者
> t = {foo = "bar"} -- same as ["foo"]="bar" (but not [foo]="bar" , that would use the variable foo)
> = t["foo"]
bar

如同数组般使用tables

> t = {"a", "b", "c"}
> = t[1] -- 注意第一个index是1,不是0
a
> = t[3]
c

--混合模式
> t = {"a", "b", [123]="foo", "c", name="bar", "d", "e"}
> for k,v in pairs(t) do print(k,v) end
1       a
2       b
3       c
4       d
5       e
123     foo
name    bar

>t = {'a', 'b','c'}
>= #t --数组t的长度
3

--add item to the end of array
> t = {}
> table.insert(t, 123)
> t[#t+1] = 456
> = t[1]
123
> = t[2]
456

--也可以指定位置insert
> t = {"a", "c"}
> table.insert(t, 2, "b")
> = t[1], t[2], t[3]
a b c

--remove
> t = {"a", "b", "c"}
> table.remove(t, 2)
> = t[1], t[2]
a c

--拼接
> t = {"a", "b", "c"}
> = table.concat(t, ";")
a;b;c

table是引用类型,意识是赋值给其他变量时不会产生copy数据

> t = {}
> u = t
> u.foo = "bar"
> = t.foo
bar
> function f(x) x[1] = 2 end
> f(t)
> = u[1]
2

许多新学习lua的喜欢把table当作数组使用,即使不需要顺序。但这样的问题是删除会很慢(需要移动其他item)检查一个item是否存在也很慢(需要轮寻全部item)

解决办法是把item存在key中,value设置一个dummy值(如true),你就可以像使用无序集合那样来使用table,快速的插入,删除和查找。

这样做的缺点是不好得到item总数(需要循环),也不能存储相同item两次

Functions

lua中定义函数如下:

function ( args ) body end

return value:

> f = function ()
>>  return "x", "y", "z" -- return 3 values
>> end
> a, b, c, d = f() -- assign the 3 values to 4 variables. the 4th variable will be filled with nil
> = a, b, c, d
x y z nil
> a, b = (f()) -- wrapping a function call in () discards multiple return values
> = a, b
x, nil
> = "w"..f() -- using a function call as a sub-expression discards multiple returns
wx
> print(f(), "w") -- same when used as the arg for another function call...
x w
> print("w", f()) -- ...except when it's the last arg
w x y z
> print("w", (f())) -- wrapping in () also works here like it does with =
w x
> t = {f()} -- multiple returns can be stored in a table
> = t[1], t[2], t[3]
x y z

参数个数可变:

> f = function (x, ...)
>>  x(...)
>> end
> f(print, 1,2,3)
1 2 3

> f=function(...) print(select("#", ...)) print(select(3, ...)) end
> f(1, 2, 3, 4, 5)
5
3 4 5

named function:

>function f(...) end -- equivalent to
>f = function(...) end

tail calls:

function factorial_helper(i, acc)
  if i == 0 then
    return acc
  end
  return factorial_helper(i-1, acc*i)
end

function factorial(x)
  return factorial_helper(x, 1)
end

Thread

lua的thread其实是协程

yielding:

> function foo()
>>   print("foo", 1)
>>   coroutine.yield()
>>   print("foo", 2)
>> end
>

using coroutine.create(fn) to create a coroutine

> co = coroutine.create(foo) -- create a coroutine with foo as the entry
> = type(co)                 -- display the type of object "co"
thread

thread state:

> = coroutine.status(co)
suspended --The state suspended means that the thread is alive, and as you would expect, not doing anything.

use coroutine.resume() to start the thread, lua will enter the thread and leave when the thread yields

> = coroutine.resume(co)
foo     1
true
> = coroutine.resume(co)
foo     2
true
> = coroutine.status(co)
dead
> = coroutine.resume(co)
false   cannot resume dead coroutine

Control Structure

if condition then
    block
elseif condition then
    block
else
    block
end

while condition do
    block
end

repeat
    block
until condition

for variable = start, stop, step do
    block
end

for var1, var2 in iterator do
    block
end

while true do
    if condition then
        break
    end
end

for i=1, 10 do
    if i > 3 then
        goto continue
    end
    block
    ::continue:: -- a name surrounded in :: :: is a goto label
end

condition and block1 or block2

Metamethods

metatable是一个包含一些metamethod的table,通过setmetatable函数把其和某个对象关联起来,那个对象就具备某些功能或能处理某些事件。因为lua是动态语言,给对象添加函数也不是什么大不了的事。

local x = {value = 5}

local mt = {
    __add = function (lhs, rhs) -- "add" event handler
        return { value = lhs.value + rhs.value }
    end
}

setmetatable(x, mt) -- use "mt" as the metatable for "x"

local y = x + x

print(y.value) --> 10

local z = y + y -- error, y doesn't have our metatable. this can be fixed by setting the metatable of the new object inside the metamethod'

getmetatable :

local y = (getmetatable(x).__add(x, x)) -- x + x

some event:

__index
__newindex
__add
__eq
__lt
__le
__metatable

Environments

lua的全局环境是一个table,全局变量就存在这个table里,我们可以为每个函数使用不同的table,这样就能看到不同的全局变量。

默认的全局table存储在一个叫“_G”的变量下

print(_ENV == _G) -- prints true, since the default _ENV is set to the global table

a = 1

local function f(t)
  local print = print -- since we will change the environment, standard functions will not be visible

  local _ENV = t -- change the environment. without the local, this would change the environment for the entire chunk

  print(getmetatable) -- prints nil, since global variables (including the standard functions) are not in the new env

  a = 2 -- create a new entry in t, doesn't touch the original "a" global
  b = 3 -- create a new entry in t
end

local t = {}
f(t)

print(a, b) --> 1 nil
print(t.a, t.b) --> 2 3'

Modules

create an example file mymodule.lua

local mymodule = {}

function mymodule.foo()
    print("hello world!")
end

return mymodule

So that you can require the same module in different files without re-running the module code, Lua caches modules in the package.loaded table.

to actually reload the module, you need:

package.loaded.mymodule = nil
mymodule = require "mymodule"

other ways to create a module:

local mymodule = {}

local function private()
    print("in private function")
end

function mymodule.foo()
    print("Hello World!")
end

function mymodule.bar()
    private()
    mymodule.foo() -- need to prefix function call with module
end

return mymodule

or 我比较喜欢的方式:

local mymodule = {}

local function private()
    print("in private function")
end

local function foo()
    print("Hello World!")
end
mymodule.foo = foo

local function bar()
    private()
    foo()
end
mymodule.bar = bar

return mymodule

package.path (for modules written in Lua) and package.cpath (for modules written in C) are the places where Lua looks for modules.

猜你喜欢

转载自blog.csdn.net/largetalk/article/details/17693297
LUA