Programming in lua (1 - 10 base)

## 此为阅读<Programming in lua>学习笔记 

Chapter 1 Hello

  • hello world
    print("hello world")
  • function
    function fact(n)
    	if n == 0 then
    		return 1
    	else 
    		return n * fact(n - 1)
    	end
    end
    
    a = io.read()
    print(fact(a))
    文件存为 hello.lua
  • run (& load library)
    lua > dofile("hello.lua") -- 导入 hello.lua包(load your library),类似python的import
        > print fact(10)
  • 访问未初始化的变量不会保存, lua变量有两种状态 nil 非nil (即存在/不存在)
  • 作用域  非local变量都为全局变量 


Chapter 2 types & values

  • lua 是动态语言, 不需要定义类型 且 lua一切都是变量
  • 基本类型 nil, boolean, number, string, userdata, function, thread, table >>> 函数 type可以测试类型
  • nil 说明 一个全局变量未赋值前为 nil ,且给一个变量赋 nil >>> 删除该变量
  • boolean ***只有false和nil为假, 其他都为真(包括0和空串)***
  • number >>>实数(数字)
  • string >>> 字符串不可变性.   [[ some strings ]] >>>类似python的 """some string"""  ***当一个字符串使用算术运算符, 其自动转换为数字类型. 相反 期望字符串的地方出现数字,数字自动转换为字符串*** 字符串连接符为 .. (双点号, 连接两边必须加空格)
  • 标准库 string库, table库, I/O库, OS库, 算术库, debug库


Chapter 3 Expression


  • 算术 二元:+-*/^(加减乘除幂) 一元:-(负)
  • 运算 <  >  <=  >=  ==  ~=  *** ==当且仅当同一对象为真, ~=当值相等(但不是同一对象)为真 eg. a = {};a.x = 1 b = {};b.x = 1    a == b -->false, a ~= b -->true .而且,a ~= a -->false***
  • 逻辑 and or not -->类似python 不同的是lua把0和空串都当真,有些运算结果和python不同, lua:  (a and b) or c -->c语言的 a ? b : c . 小技巧  x = x or v (当x为nil时给x赋值为v)
  • 串连接 .. (双点号)(左右一定要加空格)
  • 除了^和..外所有的二元运算符都是左连接的。
  • 表  1.lua表(数组下标从1开始) 2.lua表元素可以是任何元素 3.lua表元素可以是 .属性 方式创建和访问(属性不参与下标计数),可以下标访问(当然了,怎么创建就怎么访问) 4每次调用构造函数(即{}),都生成一个table
    -- 生成一个链表 <linked_list.lua> ctrl + d结束i/o输入
    list = nil
    for line in io.lines() do
        list = {next=list, value=line}
    end
    
    l = list
    print(l)
    while l do
        print(l.value)
        l = l.next
    end
    
    -- 手动修改table下标,使其下标从0开始,不推荐下标从0开始(因为和标准库不兼容)
    days = {[0]="Sunday", "Monday", "Tuesday"}
  • table可以用逗号(,)和分号(;)分割,通常用;分割不同类型元素


Chapter 4 Statements

  • 赋值语言 和python类似, 特别的a, b = a+1, b+1, b+2  -- value of b+2 is ignored
  • 显示划分代码块(block)使用do - end (类似c的{}内的部分), 块内是局部变量
    do
        local a = 2
        -- do something
    end -- scope of 'a' ends here
    print(a)
    -- result: nil
  • 控制循环 
    -- condition and cycle
    
    -- if oo then xx elseif oo then xx else xx end   oo is condition, xx is action
    a = a or 3
    if a > 3 then
        -- do someting
        print(a)
    elseif a == 3 or a ~= 3 then
        -- do someting
        print(a)
    else 
        -- do something
        print(a)
    end -- 块结束,end不可少
    
    -- while oo do xx end
    while a > 0 do
        print(a)
        a = a - 1 -- 不支持 a++, ++a, a += 1(a += 1 python支持)
    end   
    
    -- repeat xx until oo  类似c的do - while
    repeat
        print(a)
    until a == 3    
    
    -- for oo1, oo2, (oo3) do xx end   oo3是步长,默认是1
    for i=0, 3 do -- *** 包含oo2,相当于 <= , 和c/python(左闭右开)风格不同 *** 且表达式oo1,oo2,oo3只计算一次(在循环前)
        print(i)
    end    
    
    -- for oo in oos   遍历迭代子函数
    for key, value in ipairs({["a"]=2,4,5}) do -- ipairs -> build-in function 迭代table中的数组部分
        print(key, value)                -- pairs -> 迭代整个table元素包括数组部分和非数组部分(数组部分:下标是数字并且不是0,非数组部分下标是串/record风格/0)
    end                                  -- io.lines -> 迭代文件每行
                                         -- string.gmatch -> 迭代字符串单词


Chapter 5 Function


  • lua的实参和形参的匹配和赋值类似:多余的部分被忽略,缺少的部分用nil补足
    -- prototype
    function f(a, b) 
    	return a or b
    end
    
    -- call
    f(3)       -- a = 3, b = nil
    f(3, 4)    -- a = 3, b = 4
    f(3, 4, 5) -- a = 3, b = 4, (5 is discarded)
  • 可以返回多个结果值(和python返回tuple类似)
    -- prototype
    function f()
    	return a, b
    end
    
    -- call
    m = f()        -- m = a
    m, n = f()     -- m = a, n = b
    m, n, q = f()  -- m = a, n = b, q = nil
  • 一个特殊函数unpack, 接受数组作为输入参数, 返回数组所有元素(貌似python不需要这样的函数, 接受迭代器就行了)
    fp = string.find  -- 函数指针
    a = {"hello", "ll"}
    print(fp(unpack(a)))  -- > 3 4
  • 可变参数, 和c类似, 用arg表存放可变参数, arg有一个域n表示参数个数(仅可变参数的个数), unpack arg是个好主意
    -- prototype
    function f(a, b, ...)
    end
    
    -- call
    f(3)          -- a = 3, b = nil , arg = {n=0} 
    f(3, 4)       -- a = 3, b = 4, arg = {n=0}
    f(3, 4, 5, 6) -- a = 3, b = 4, arg = {5, 6; n=2}
  • 虚变量 用下滑线_表示, 一般不想要前面的返回值,使用它起着占位的作用 eg local _, x = string.find("hello", "ll") -- x = 4


Chapter 6 More About Functions

  • Lua函数是带有词法定界(lexical scoping)的第一类值(first-class values).
  • 既然函数是值,那么创建函数其实可以:
    -- function foo(x) return x ^ 2 end 形式其实是语法甜头
    -- 这个是真正的形式
    foo = function (x)
    	return x ^ 2 -- python的幂是 ** (c ^表示异或)
    end
    
    
    --
  • 高阶函数 
    -- 类似python的 sorted (stl 的sort algorithm)
    
    users = {
    {name="zhangsan", score=90},
    {name="lisi", score=88},
    }
    
    table.sort(users, function (a, b) return (a.name > b.name) end) -- 通过表的name域排序
  • 闭包 当一个函数内部嵌套另一个函数定义时, 内部的函数体可以访问外部的局部变量(***upvalue), 这种特征称作词法定界 ***upvalue:
    function newCounter()
    	local i = 0        -- upvalue
    	return function()  -- anonymous function
    		i = i + 1
    		return i
    	end
    end
    
    c1 = newCounter()
    print(c1()) --> 1
    print(c1()) --> 2
  • 闭包 重定义函数 
    -- 可以重新包装函数, 实现新功能
    -- 重定义sin函数, 使其接受角度而不是弧度
    
    math.sin = function(x)
    	return math.sin(x * math.pi / 180) -- x is upvalue
    end
  • 闭包 重定义函数2
    -- 可以重新包装函数, 实现新功能
    -- 重定义sin函数, 使其接受角度而不是弧度
    
    do 
    	local oldSin = math.sin
    	math.sin = function(x) --*1
    		return oldSin(x * math.pi / 180)
    	end
    end
    
    -- do -- end 代码块:由于oldSin是局部变量, 而新定义的math.sin(*1行)是全局的,所以只可以用新版本的math.sin函数  把不安全代码函数重定义并发在局部代码块类, 类似于沙箱
  • 非全局函数 
    -- 函数作为table的域 (方式1)
    Lib = {}
    Lib.add = function (x, y) return x + y end
    Lib.sub = function (x, y) return x - y end
    
    -- 函数作为table的域 (方式2)
    Lib = {
    add = function (x, y) return x + y end, 
    sub = function (x, y) return x - y end,
    
    }
    
    -- 函数作为table的域 (方式3) 
    Lib = {}
    function Lib.add(x, y)
    	return x + y
    end
    -- ...
    
    -- 定义局部函数(函数就是变量)
    local f = function (x, y) return x + y end
    -- 或者
    local function f(x, y)
    	return x + y
    end
    
    -- 局部函数前向申明(当是递归时, 内部并不知道自己是局部函数, 还会去全局查找, 找不到还好, 万一找到了就不好了,哈哈)
    local fact                 -- *1
    fact = function (n)
    	if n == 0 then
    		return 1
    	else
    		return n*fact(n-1) -- 如果没有 *1 它就去全局查找fact了
    	end
    end
    
    -- 迷宫游戏(状态机), 从room1开始,走到room4
    function room1()
    	local move = io.read()
    	if move = "S" then
    		return room3()
    	elseif move = "E" then
    		return room2()
    	else
    		print("invalid move")
    		return room1()       -- stay the same room
    	end
    end
    
    function room2()
    	local move = io.read()
    	if move = "S" then
    		return room4()
    	elseif move = "W" then
    		return room1()
    	else
    		print("invalid move")
    		return room2()       -- stay the same room
    	end
    end
    
    function room3()
    	local move = io.read()
    	if move = "N" then
    		return room1()
    	elseif move = "E" then
    		return room4()
    	else
    		print("invalid move")
    		return room3()       -- stay the same room
    	end
    end
    
    function room4()
    	print("you go out the maze")
    end
  • ing

转载于:https://my.oschina.net/1123581321/blog/159626

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值