Programming in lua 杂记(转)

简介: 1,loadstring 编译的时候不关心词法范围:   local i = 0   f = loadstring("i = i + 1")   g = function () i = i + 1 end    这个例子中, 和想象的一样g 使用局部变量i , 然而f 使用全局变量i ; loadstring 总是在全局环境中编译他的串。
1, loadstring 编译的时候不关心词法范围:
  local i = 0
  f = loadstring("i = i + 1")

  g = function () i = i + 1 end 

  这个例子中, 和想象的一样g 使用局部变量i , 然而f 使用全局变量i ; loadstring 总是在全局环境中编译他的串。

i = 100
local i = 0
f = loadstring("i = i + 1  print(i)")
g = function () i = i + 1 print(i) end 

print(f())
print(g())
-- 输出结果:
101
1

 

2,require 和dofile 完成同样的功能但有两点不同:

    => require 会搜索目录加载文件

    => require 会判断是否文件已经加载避免重复加载同一文件。由于上述特征, require 在Lua 中是加载库的更好的函数。

   为了确定路径, Lua 首先检查全局变量LUA_PATH 是否为一个字符串, 如果是则认为这个串就是路径; 否则require 检

   查环境变量LUA_PATH的值, 如果两个都失败require 使用固定的路径( 典型的"?;?.lua" ) 

 

  Lua 保留一张所有已经加载的文件的列表( 使用table 保存) 。如果一个加载的文件在表中存在require 简单的返回; 表 

  中保留加载的文件的虚名, 而不是实文件名。所以如果你使用不同的虚文件名require 同一个文件两次,将会加载两次该文

  件。比如require "foo" 和

  require "foo.lua" , 路径为"?;?.lua" 将会加载foo.lua 两次。我们也可以通过全局变量_LOADED访问文件名列表。

  在require运行一个chunk 以前, 它定义了一个全局变量_REQUIREDNAME 用来保存被required 的虚文件的文件名。 

  dofile当作Lua运行代码的chunk的一种原始的操作。dofile实际上是一个辅助的函数。真正完成功能的函数是loadfile;与dofile不同的是loadfile编译代码成中间码并且返回编译后的chunk作为一个函数,而不执行代码;另外loadfile不会抛出错误信息而是返回错误代。我们可以这样定义dofile:

  function dofile (filename)
       local f = assert(loadfile(filename))
       return f()
 end
如果loadfile失败assert会抛出错误。loadfile更加灵活。在发生错误的情况下,loadfile返回nil和错误信息,这样我们就可以自定义错误处理。另外,如果我们运行一个文件多次的话,loadfile只需要编译一次,但可多次运行。dofile却每次都要编译。

 

3,lua的错误处理(断言)

   n = assert(io.read("*number"), "invalid input") 

   assert 首先检查第一个参数, 若没问题, assert不做任何事情; 否则, assert 以第二个参数作为错误信息抛出。第二个参

   数是可选的。注意, assert 会首先处理两个参数, 然后才调用函数。

   基本的原则是: 对于程序逻辑上能够避免的异常, 以抛出错误的方式处理之, 否则返回错误代码。

 

4,如果在Lua 中需要处理错误, 需要使用pcall 函数封装你的代码。 

  if pcall(function () ... end) then ...else ... 

  local status, err = pcall(function () error({code=121}) end)

  print(err.code) --> 121 

  两个常用的debug 处理函数: debug.debug 和debug.traceback;

  也可以用xpcall来来处理错误,并可将其封装为此下trycall函数(方便使用):

-- 打印错误信息
local function __TRACKBACK__(errmsg)
    local track_text = debug.traceback(tostring(errmsg), 6);
    print("---------------------------------------- TRACKBACK ----------------------------------------");
    print(track_text, "LUA ERROR");
    print("---------------------------------------- TRACKBACK ----------------------------------------");
    local exception_text = "LUA EXCEPTION\n" .. track_text;
    return false;
end

--[[ 尝试调一个function 这个function可以带可变参数
如果被调用的函数有异常 返回false,退出此方法继续执行其他代码并打印出异常信息;]]
function trycall(func, ...)
    local args = { ... };
    return xpcall(function() func(unpack(args)) end, __TRACKBACK__);
end
--测试代码:

trycall(function(param)
      print("message "..param)
      print("message "..nil)
        end, "test trycall")

 

5,lua中的对象

 当一个表的metatable存在一个__index函数时,如果Lua调用一个原始表中不存在的函数,Lua将调用这个__index指定的函数。 

 这样可以用__index实现在多个父类中查找子类不存在的域。

 

6,变长参数
  必须作为最右边的形参出现,function f(...) return ... end...不是一个table,而是一个多值,所以可以像其他多值一样使用  

   local a, b = ...如果需要作为table使用,则将其放  入{} 即可for i,v in ipairs({...}) do print(v) end如果...中含有nil,则

   最好通过 select函数来访问for i=1, select("#", ...) do print(select(i, ...)) end 

 

 7,解释器

    lua [options] [script [args]]
    -e stat: executes string stat;
    -l mod: "requires" mod; 
    -i: 在执行完其他选项之后,进入交互模式
   各选项会依序处理,如
   $ lua -e'a=1' -e 'print(a)' script.lua
   $ lua -e"_PROMPT='myprompt> '" -i
    命令行参数为arg,脚本参数的下标从1开始,如果定义了环境变量LUA_INIT,那么该变量对应的文件将会首先执行
    交互模式中=开始的表达式等价于print该表达式的值
   >a=5
   >=a --等价于print(a)
  

 8.__call元方法释义

    当我们写下a(b,c )时,若a不是函数,那么a.metatable.__call(a, ...)将调用:
meta = {}
meta.__call = function(obj, param1, param2)
  print(obj, param1, param2)
  print(obj.test)
end
a = {}
setmetatable(a, meta)
a.test = "Oh-yeah"
a(a.test, 99)

-- 输出结果:

table: 0x7fd2f9404fc0 Oh-yeah 99
Oh-yeah

倾城之链 | NICE LINKS DJI Mavic Air
目录
相关文章
|
小程序 前端开发 JavaScript
微信小程序框架---详细教程
微信小程序框架---详细教程
369 0
|
5月前
|
监控 Java 数据库连接
Java一分钟之-Spring Boot:快速开发微服务
【6月更文挑战第7天】本文探讨了Spring Boot开发中的常见问题,包括起步依赖与版本管理、自动配置、启动类位置、日志配置、数据库连接、错误处理和Actuator监控。建议使用最新稳定版Spring Boot,通过`spring-boot-starter-parent`管理版本,理解自动配置原理,正确放置启动类,配置日志级别,准确设置数据库连接参数,自定义全局异常处理器,以及启用Actuator进行监控。不断学习和实践是应对各种问题的关键。
58 1
|
存储 缓存 自然语言处理
小刚带你深入浅出理解Lua语言
前言这篇文章并不是针对某个知识点深入剖析,而是聚焦在Lua语言的关键知识点覆盖和关键使用问题列举描述。能够让学习者对Lua整体有个认识(使用一门新的语言不仅仅在用的时候适应它,而是知道怎么善于使用它),同时也可以作为一个工具文档在Lua中遇到具体问题的时候能从这里索引到相应的知识点和Lua的一些原理,得到启发。 1、Lua语言的特点简单的说Lua语言是一个可扩展的嵌入型的脚本语言。它具有以下的特点
小刚带你深入浅出理解Lua语言
跟着Cell学作图 | 双曲线火山图
跟着Cell学作图 | 双曲线火山图
388 0
跟着Cell学作图 | 双曲线火山图
|
Java 程序员 编译器
【Java】异常处理机制
【Java】异常处理机制
93 0
【Java】异常处理机制
|
存储 关系型数据库 MySQL
MySQL数据类型DECIMAL用法
当我们需要存储小数,并且有精度要求,比如存储金额时,通常会考虑使用DECIMAL字段类型,可能大部分同学只是对DECIMAL类型略有了解,其中的细节还不甚清楚,本篇文章将从零开始,为你讲述DECIMAL字段类型的使用场景及方法。
640 0
haskell简明入门(一)
本文的主要内容参考自《Haskell趣学指南》 1. What is Haskell?     以下内容引用自Haskell官网: Haskell是一个先进的,纯粹的函数式编程语言。一个典型的声明式地,静态类型的代码如下: primes = filterPrime [2.
1503 0
|
Python
Python3快速入门——(10)函数式编程(Functional Programming)
#函数本身也可以赋值给变量,即:变量可以指向函数 f=abs #abs()和f()等价了 变量可以指向函数,函数名也是变量 g=f(-10) #10 #变量可以指向函数,函数的参数能接收变量,...
1094 0
|
Java
《Clojure程序设计》——导读
本节书摘来自异步社区《Clojure程序设计》一书中的导读,作者 【美】Stuart Halloway , Aaron Bedra,更多章节内容可以访问云栖社区“异步社区”公众号查看
2045 0