Lua学习一

本文相当于《lua程序设计第二版》的一个笔记 (本书一共31章节)

lua下载

第一章,开始

print("hello world")

将上面这个保存到 hello.lua 文本中,然后 lua hello.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(fact(a))

运行如下:

 E:\program\lua 的目录

2015/06/24  10:44    <DIR>          .
2015/06/24  10:44    <DIR>          ..
2015/06/24  10:41               200 fact.lua
2015/05/19  22:49           298,917 lua53.dll
2015/04/24  01:03            93,861 lua53.exe
2015/05/19  22:51           228,669 luac53.exe
2015/05/19  22:51            95,533 wlua53.exe
               5 个文件        717,180 字节
               2 个目录 234,745,798,656 可用字节

E:\program\lua>lua53 fact.lua
enter a number:
5
120

E:\program\lua>

1.1 程序块

lua多条语句可以使用也可以不适用分号(;)比如下面的语句是一样的

a=1
b=a*1
-----------
a=1  b=a*2

运行 lua进入交互模式

E:\program\lua>lua53
Lua 5.3.0  Copyright (C) 1994-2015 Lua.org, PUC-Rio
>

1.1未完待续

1.2词法规范

lua的标识符 字母数字下划线(数字不能开头),下划线和大写字母开头在lua中专用特殊用途,lua区分大小写,and是一个保留字,lua的保留字有一下:

--lua 保留字
and break do else elseif end
false for function if in
local nil not or repeat
return then true until while

1.3 全局变量

全局变量不需要声明,比如 a=1 就会产生一个全局变量,lua中访问一个没声明的变量不会发生错误,会得到一个nil

1.4解释器程序
未完待续

第二章 类型和值

--lua有8种基本类型
--nil(空) boolean(布尔) number(数字) string(字符串) 
--userdata(自定义类型) function(函数) thread(线程) table(表)
print(type("hello world"))--string
print(type(10.4*3))--number
print(type(print))--function
print(type(type))--function
print(type(true))--boolean
print(type(nil))--nil
print(type(type(X)))--string

lua中函数是作为第一类值对待

2.1 nil(空)
全局变量赋值前就是nil ,将nil赋值给一个全局变量相当于删除它,nil(无效数值)
2.2 boolean
lua中除了 false和nil,其他都是真
2.3 number
number 类型表示实数, 4 ,0.4, 4.75e-3
2.4 string
未完待续
2.5 table 表
未完待续
2.6function(函数)
未完待续

第三章 表达式

lua 支持的算术操作符有+-*/%就基本的这些都有

3.2 关系操作符
<,>,<=,>=,~=(不等) nil只与自身相等。
字符串比较是按字母次序。
数字和字符串之外的其他类型只能进行相等性或不等性比较。
3.3逻辑操作符
逻辑运算符 and or not ,
and和or使用“短路求值”
3.4字符串连接
字符串连接是“..”(两个点)操作符

a="hello "
print(a.."world")--hello world

3.5 优先级

 1.   ^
 2.   not # -
 3.   * / %
 4.   + -
 5.   ..
 6.   < > <= >=  ~=  ==
 7.   and 
 8.   or

3.6 table构造式
待续

第四章

4.1赋值
lua允许多重赋值a,b=1,2这样,交换a,b=b,c 如果有多余的则赋值为nil,也就是静静的丢弃掉
4.2局部变量与块

j=10      --全局变量
local i=1 --局部变量,通过local语句创建局部变量

局部变量的作用域仅限于声明他们的那个快,一个快是一个控制结构的执行体,或者是一个函数的执行体,再或者是一个程序块

x=10
local i=1   --程序块中的局部变量 
while 1<=x do
   local x=i*2 --while循环体中的局部变量
   print(x)    --2,4,6,8
   i=i+10
end

if i>20 then
   local x   --then 中的局部变量
   x=20
   print(x+2)  --如果测试成功会打印22
else
   print(x)    --10 全部变量
end

print(x)      --10 全部变量

尽可能使用局部变量是一个好的编程习惯

在lua中 local foo=foo 将全部变量赋值给局部变量
4.3控制结构
if a<0 then a=0 end
嵌套if可以使用elseif可以避免潜逃中出现的多个end

if op=="+" then 
  r=a+b
elseif op=="-" then
   r=a-b
else
   error("ddddd")
end

while

local i=1
while a[i] do
  print(a[i])
  i=i+1
end
repeat
  line=io.read()
  until line~=""
print(line)--repeat中的局部变量在until中仍然可以访问到

数字for

for i=1 ,f(x) do print(i) end--第三个表达式可选的,如果不指定则加1
for i=1 ,f(x),-1 do print(i) end

泛型for

for k in pairs(t) do print(k) end

4.4break与return
break和return 没啥好说的。

第五章 函数

一个函数若只有一个参数,并且此参数是一个字面字符串或者table构造式,那么圆括号可有可无,如:

print "hello world" --print("hello world")
dofile 'a.lua'      --dofile('a.lua')
print[[a multi-line message]] --print([[a multi-line message]])
f{x=10.y=20} --f({x=10.y=20})
type{}       --type({})

lue为对象式调用提供了一种特使的用法-冒号操作符:o.foo(o,x) 另一种写法o:foo(x)

function f(a,c) return a or b end--一个函数
f(3)--a=3  b=nil
f(3,4)--a=3,b=4
f(3,4,5)--a=3,b=4,5被丢弃

5.1多重返回值

s,e=string.find("hello Lua users","Lua")
print(s,e)--7  9这是一个多返回值

5.2变长参数

function add(...)
local s=0
  for i,v in ipairs{...} do
   s=s+v
   end
  return s
end
print(add(3,4,10,25,12))--54可变参数

5.3具名实参
待续

第六章 深入函数

6.1 closure闭合函数

若一个函数写在另一个函数的内部,内部的函数可以访问外部函数的局部变量,这个叫做“词法域”。

--这是一个对学生姓名进行排序的例子
names={"Peter","Paul","Mary"}
grades={Mary=10,Paul=7,Peter=8}
table.sort(names,function(n1,n2)
 return grades[n1]>grades[n2]--比较年级
end)

--假设我们要自己实现这个例子
function sortbygrade(names,grades)
table.sort(names,function()
    return grades[n1]>grades[n2]--比较年级
end)
end
--在这里例子中匿名函数是函数可以访问grades
--而grades是sortbygrade的局部变量。在这个匿名函数的内部,grades
--既不是全局变量也不是局部的,在lua中叫做"非局部的变量"
--附:这个其实就是自由变量了。

为什么lua允许这样访问呢,原因在于函数是”第一类值”(先解释第一类值
在JavaScript中 var c=function(){} 这样可以把一个函数赋值给一个变量,函数和number一样,这样的语言就是 所谓的第一类值,比如java中,就没办法这么做。)

function newCounter()
local i=0
 return function()
        i=i+1
        return i
        end
end
---------------
c1=newCounter()
print(c1())--1
print(c1())--2
----------------
c2=newCounter()
print(c2())--1
print(c1())--3
print(c2())--2
--如上 书上这么说的  从技术上讲,Lua中只有closure  而不存在"函数" 因为函数本身就是一种特殊的clousure
--注意 在这里创建闭合函数的时候其实做了一个i的副本。就是说有几个闭包就有几个i的副本。
--这个其实也没啥。他只有可能这么干。

这段代码我翻译成js试试 如下,结果是一致的,他只有可能这么干
function newCounter(){
var  i=0
 return function(){
        i=i+1
           return i
        }
}
//---------------
var  c1=newCounter()
console.log(c1())//1
console.log(c1())//2
//----------------
var c2=newCounter()
console.log(c2())//1
console.log(c1())//3
console.log(c2())//2

6.2非局部的函数
没啥说的,意思函数可以存放table中,存放到其他数据结构中
6.3正确的尾调用
lua支持尾递归优化,赞。虽然语言支持尾递归,但是必须写出尾递归的代码才行。

function foo(n)
 if n>0 then return foo(n-1) end
end
--比如这个代码,无论n是几,都不会出现栈溢出。因为程序不需要记录之前栈调用。这个代码在java中试了一下java.lang.StackOverflowError ,果然java不支持尾递归。

在lua中,只有 return[func][args]这样才算是“尾调用”

lua尾调用待续

附录:

① -#是表的长度运算符 t = {“a”, “b”, “c”, “d”},#t –输出是4
②:
Lua中的
loadfile只加载文件,啥都不做
dofile加载文件并且执行文件的内容
require加载文件并且只执行一次

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值