Lua中的源代码预编译浅析

尽管Lua被称为是一种解释型的语言,但Lua确实允许在运行源代码之前,将源代码预编译成一种中间形式(类比Python的.pyc)。区别解释型语言的主要特征在于编译器是否是语言运行时库的一部分,即是否有能力执行动态生成的代码(Lua可以通过dofile执行Lua代码)。

其实,dofile的核心功能是由loadfile完成的,可以这样来定义dofile:

loadfile并不是执行代码,而只是编译,返回一个函数,由dofile执行。
如果多次运行一个文件,可以只调用一次loadfile,重复调用其返回的函数即可。
  
另外一个函数,loadstring从字符串加载代码:

代码如下:

> f = loadstring('print "hello"')
> f()
hello

考察一下loadstring代码的执行域

代码如下:

> i = 1
> f = loadstring('i = i + 1')
> =i
1
  
--不要完了交互式命令行中,一行代码默认一个block
  
> f = loadstring('i=i+1')
> do
>> local i =1
>> f()
>> print(i)
>> end
1
  
> do
>> local i = 1
>> local f = loadstring('i=i+1')
>> f()
>> print(i)
>> end
1

两次运行,都是将global中的i加1.
可以这样理解f:

代码如下:

function f()
i = i+1
end

但如果直接替换,其结果并不一致。

代码如下:

> do
>> local i =1
>> function f()
>> i = i + 1
>> end
>> f()
>> print(i)
>> end
2

可以认为,loadstring编译出的函数,会关联global scope,因而不会表现出闭包的特性,故而,应该尽量不使用这种方式!
  
另外,如果语法有误,那么loadstring返回nil。
可以使用assert(loadstring(s))()的方式。
如果参数不是nil/false,返回参数,否则assert error;
  
深究一下loadfile和loadstring就会知道,Lua中其实有一个load函数,后者接收一个reader function,调用其读取代码;

(0)

相关推荐

  • Mac平台中编译安装Lua运行环境及Hello Lua实例

    1.下载Lua安装包 下载地址:http://www.lua.org/download.html,目前最新的Lua是5.2.3.解压得到doc.src.Makefile.README共4个文件. 2.编译Lua环境 1)控制台下cd  Lua解压路径. 2)执行make  平台,我是Mac,所以执行make macosx: 3)在src中生成lua和luac两个可执行文件,这两个文件可以单独拿出来,比如我们在Lua解压路径下创建bin目录,将生成的可执行文件放进去. 3.Hello Lua 1)

  • Lua中编译执行代码相关的函数详解

    可以说Lua之所以称为是一种解释型的语言,正是因为有诸如load这样的函数,因为这样的函数使得Lua可以执行动态生成的代码.下面具体来分析这些函数. load函数 load函数原型如下: 复制代码 代码如下: load (chunk [, chunkname [, mode [, env]]]) 该函数加载一个chunk,如果没有错误,则返回一个函数.如果传入chunk的值是一个字符串,则就加载这个字符串:如果传入chunk的值是一个函数,则这个函数必须返回一个字符串,并且load会一直调用这个

  • Lua简介、编译安装教程及变量等语法介绍

    公司业务有用到Lua,与nginx结合起来实现高性能的web应用,想去弄懂这方面的知识,就去了解学习了下Lua,欢迎大咔们指教. 1. Lua介绍 Lua是一门简单的编程语言,它的优势在于可以整合C++的模块来扩展自身的功能,使用数百行或更少的代码来解决复杂的问题.具有的特征有: 1.1. 可扩展性:Lua从一开始就被设计成易于扩展的语言,很多功能都是通过外部库来实现的,很容易与其他编程语言如C.C++.Java等等进行交互. 1.2. 简洁: Lua十分简洁,但是功能强大,易于学习,很适合小规

  • Lua中使用元表(metatable)执行算术类元方法实例

    上一节对元表和元方法有了一个初步的认识,这篇就来举个最简单的例子吧,加深一下印象,也为后续内容做准备. 1.元方法名 Lua其实已经规定好了各种算术操作符的元方法名字,如: __add:加法 __sub:减法 __mul:乘法 __div:除法 __unm:相反数 __mod:取模 __pow:乘幂   只要在自定义元表的时候,给这些元方法名赋予新的函数就可以实现自定义操作了. 2.例子 开始举例吧,我们新建一个自定义的元表(也就是一个table变量),用来定义一些操作: 复制代码 代码如下:

  • Lua中的源代码预编译浅析

    尽管Lua被称为是一种解释型的语言,但Lua确实允许在运行源代码之前,将源代码预编译成一种中间形式(类比Python的.pyc).区别解释型语言的主要特征在于编译器是否是语言运行时库的一部分,即是否有能力执行动态生成的代码(Lua可以通过dofile执行Lua代码). 其实,dofile的核心功能是由loadfile完成的,可以这样来定义dofile: loadfile并不是执行代码,而只是编译,返回一个函数,由dofile执行. 如果多次运行一个文件,可以只调用一次loadfile,重复调用其

  • Lua中字符串(string)浅析

    Lua中字符串可以使用""或''声明,类似Javascript中的用法. 复制代码 代码如下: > ="sdfdsf" sdfdsf > ='sfdd' sfdd > ='abc"' abc" > ="abc'" abc' 同Java.Python一样,Lua的字符串是不可修改的值,可以通过string.gsub函数来替换字符串中的子串: 复制代码 代码如下: > s = string.gsub(

  • 巧用ASP.NET预编译Web应用程序规避调用延迟的方法

    自从ASP.NET面市以来,开发人员一直都在要求(微软)出台一个解决办法,而ASP.NET 2.0利用预编译提供了一个有效的解决方案. 预编译选项 在首次启动应用程序的时候,ASP.NET会动态地分析和编译所有的ASP.NET文件(aspx页面).运行环境要对编译的结果进行缓冲,以便更好地服务未来所有的请求. 在服务器重启或者Web服务器重启之后,第一次启动应用程序也意味着这一过程要重新开始.而且,对应用程序任何文件的改变都会被系统检测到,而在文件发生改变之后首次运行应用程序也会让这一过程再次发

  • JavaScript运行过程中的“预编译阶段”和“执行阶段”

    javascript相对于其它语言来说是一种弱类型的语言,在其它如java语言中,程序的执行需要有编译的阶段,而在javascript中也有类似的"预编译阶段"(javascript的预编译是以代码块为范围<script></script>,即每遇到一个代码块都会进行  预编译>执行),了解javascript引擎的执行机理,将有助于在写js代码过程中的思路总结 首先科普下javascript中的两种声明方式,var和function,前者声明的是变量,后

  • 解析VC中预编译头文件的深入分析

    一.为什么预编译头文件:预编译头的概念: 所谓的预编译头就是把一个工程中的那一部分代码,预先编译好放在一个文件里(通常是以.pch为扩展名的),这个文件就称为预编译头文件这些预先编译好的代码可以是任何的C/C++代码,甚至是inline的函数,但是必须是稳定的,在工程开发的过程中不会被经常改变.如果这些代码被修改,则需要重新编译生成预编译头文件.注意生成预编译头文件是很耗时间的.同时你得注意预编译头文件通常很大,通常有6-7M大.注意及时清理那些没有用的预编译头文件.也许你会问:现在的编译器都有

  • JDBC之PreparedStatement类中预编译的综合应用解析

    预编译的优点1.PreparedStatement是预编译的,对于批量处理可以大大提高效率. 也叫JDBC存储过程. 2.使用 Statement 对象.在对数据库只执行一次性存取的时侯,用 Statement 对象进行处理.PreparedStatement 对象的开销比Statement大,对于一次性操作并不会带来额外的好处. 3.statement每次执行sql语句,相关数据库都要执行sql语句的编译,preparedstatement是预编译得,   preparedstatement支

  • 浅谈VC中预编译的头文件放那里的问题分析

    用C++写程序,肯定要用预编译头文件,就是那个stdafx.h.不过我一直以为只要在.cpp文件中包含stdafx.h 就使用了预编译头文件,其实不对.在VC++中,预编译头文件是指放到stdafx.h中的头文件才会有效果.如下: file: stdafx.h 复制代码 代码如下: // stdafx.h : include file for standard system include files,// or project specific include files that are u

  • Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库

    Note:这篇文章是基于Android Studio 3.01版本的,NDK是R16. step1:创建一个包含C++的项目 其他默认就可以了. C++ Standard 指定编译库的环境,其中Toolchain Default使用的是默认的CMake环境:C++ 11也就是C++环境.两种环境都可以编库,至于区别,后续会跟进,当前博文使用的是CMake环境. Exceptions Support 如果选中复选框,则表示当前项目支持C++异常处理,如果支持,在项目Module级别的build.g

  • 浅析JavaScript预编译和暗示全局变量

    1. 暗示全局变量 未声明的变量称为暗示全局变量. var a = 1; //函数体外声明的变量称为全局变量 b = 2; // 无论函数体外或函数体内未声明的变量都称为暗示全局变量 function fn() { var c = 3; //函数体内声明的变量称为局部变量 d = 4; // 暗示全局变量 } fn(); // 若不执行函数,则不会进行函数预编译,d 就不会提升为全局变量 console.log(c); // error: c is not defined console.log

  • Lua中的table浅析

    Lua的table提供了Map的功能,实现了"关联数组",并且整数.字符串甚至nil都可以作为索引/key:table没有固定的大小.   基于table,可以表示普通数组.符号表.集合.记录.队列和其他数据结构.   而Lua也是通过table来解决模块(module).包(package)和对象(Object)的. 例如io.read表示使用"read"来索引table io.   在Lua中,table既不是值也不是"变量",而是对象,可以

随机推荐