Lua支持“尾调用消除(tail-call elimination)”.尾调用(tail call):当一个函数调用是另一个函数的最后一个动作时,该调用才算是一条“尾调用”.例如,下面的代码就是一条“尾调用”: function f (x) return g(x) end 也就是说,当f调用完g之后就再无其他事情可做了.因此在这种情况下,程序就不需要返回那个“尾调用”所在的函数了.所以在“尾调用”之后,程序也不需要保存任何关于该函数的栈(stack)信息了.当g返回时,执行控制权可以直接返回到调…
在程序设计中,递归(Recursion)是一个很常见的概念,合理使用递归,可以提升代码的可读性,但同时也可能会带来一些问题. 下面以阶乘(Factorial)为例来说明一下递归的用法,实现语言是PHP: <?php function factorial($n) { if ($n == 0) { return 1; } return factorial($n - 1) * $n; } var_dump(factorial(100)); ?> 如果安装了XDebug的话,可能会遇到如下错误: Fa…
<Lua程序设计(第2版)> 6.3 正确的尾调用(proper tail call) Lua是支持尾调用消除(tail-call elimination)的,如下面对函数g的调用就是尾调用. function f(x) return g(x) end 尾调用之后,程序不需要保存任何关于函数f的栈(stack)信息,即不耗费任何栈空间. 尾调用方法可用于编写状态机(state machine),类似于goto到另一个函数,如果没有尾调用消除,每次调用都会创建一个新的栈层(stack level…
文章来源自:http://www.zhufengpeixun.com/qianduanjishuziliao/javaScriptzhuanti/2017-08-08/768.html JavaScript 中的尾调用优化(tail call optimization) 我在学习尾调用优化的过程中,有两个误解: 第一个是,我们一谈优化,经常说时间的优化.但是尾调用优化却主要是指空间的优化. 第二个是,既然尾调用优化是在 es6 中支持的,那么可能又要学新的语法了.然而,尾调用优化并不需要新的语法…
一.箭头函数 箭头函数(Arrow Function)是ES6提供的一个很实用的新功能,与普通函数相比,不但在语法上更为简洁,而且在使用时也有更多注意点,下面列出了其中的三点: (1)由于不能作为构造函数,因此也就没有元属性(new.target)和原型(prototype属性). (2)函数体内不存在arguments.super和this,即没有为它们绑定值. (3)当需要包含多个参数时,它们的名称不可重复. 1)语法 箭头函数由三部分组成:箭头(=>).参数和函数体,省略了名称和funct…
什么是尾调用? 尾调用(Tail Call)是函数式编程的一个重要概念,就是指某个函数的最后一步是调用另一个函数. function f(x) { return g(x) } 如上,函数 f 的最后一步是调用函数g,这就叫做尾调用. 但是,如下情况并不属于尾调用: // 情况一 function f(x) { let y = g(x); return y; } // 情况二 function f(x) { return g(x) + 1; } // 情况三 function f(x) { g(x…
背景: 今天聊代码规范的问题的时候说了一下尾调用的问题. 一:概念: 什么是尾调用? 尾调用(Tail Call):某个函数的最后一步仅仅只是调用了一个函数(可以是自身,可以是另一个函数). 注意 “仅仅” 两个字. 例子: // 尾调用: - (NSInteger)funcA:(NSInteger)num { /* Some codes... */ if (num == 0) { return [self funcA:num];// 尾调用->自身 } if (num > 0) { retu…
尾调用是指在函数return时直接将被调函数的返回值作为调用函数的返回值返回,尾调用在很多语言中都可以被编译器优化, 基本都是直接复用旧的执行栈, 不用再创建新的栈帧, 原理上其实也很简单, 因为尾调用在本质上看的话,是整个子过程调用的最后执行语句, 所以之前的栈帧的内容已经不再需要, 完全可以被复用.报错的回溯日记,因为旧的执行栈已经没了,所以报错日记只显示(tail call).一般调用栈的长度为1M到2M,保存了调用过程中的参数和相关环境,如果递归调用太长,就会溢出.尾调用就能解决递归函数…
尾调用(Tail Call) 尾调用是函数式编程里比较重要的一个概念,它的意思是在函数的执行过程中,如果最后一个动作是一个函数的调用,即这个调用的返回值被当前函数直接返回,则称为尾调用,如下所示: function f(x) { return g(x) } 在 f 函数中,最后一步操作是调用 g 函数,并且调用 g 函数的返回值被 f 函数直接返回,这就是尾调用.而下面这个栗子就不是尾调用: function f(x) { return 1 + g(x) } 原因是它的最后一步操作是将 g 函数…
引导语 本文从一个递归栈溢出说起,像大家介绍一下如何使用尾调用解决这个问题,以及尾调用的原理,最后还提供一个解决方案的工具类,大家可以在工作中放心用起来. 递归-发现栈溢出 现在我们有个需求,需要计算任意值阶乘的结果,阶乘我们用 n!表示,它的计算公式是:n! = 123--(n-1)n,比如说 3 的阶乘就是 123. 对于这个问题,我们首先想到的应该就是递归,我们立马写了一个简单的递归代码: // 阶乘计算 public static String recursion(long begin,…
{--1.环境--} 为了快速入手,使用了小巧快速的vc++6.0编译器 以及在官网下载了Lua安装包..官网地址{--http://10.21.210.18/seeyon/index.jsp--} 两者都安装好后,即可进行 {--2.工程以及配置--} 1.首先用vc++6.0创建一个简单的win32 console application 2.从Lua的安装目录下复制include和lib两个目录下的文件到刚刚创建的工程的目录下. {include:包含了lua的.h头文件} {lib:包含…
Eclipse中Android公共库的正确建立及调用方法 引言 之前一直头痛于没有办法在多个程序中共享资源,用作公共类库的方法也是使用的导出jar再导入的办法,现在终于初步搞明白了,可算解脱了~,分享出来. 建立公共库 首先建立公共库的Android项目,名为MyCoreLib: 完成后在左侧包浏览器里右键点选我们新建的这个项目,选择Properties项: 左侧选择Android分类,右侧勾选Is Library选项: 完成后在包资源管理器中删除默认生成的资源,以避免以后被引用时冲突: 打开A…
项目开发中一些常用的es6知识,主要是为以后分享小程序开发.node+koa项目开发以及vueSSR(vue服务端渲染)做个前置铺垫. 项目开发常用es6介绍 1.块级作用域 let const 2.箭头函数及this指向 3.promise. 4.async await语法 4.模块化 module export和import 5.解构赋值.字符串模板 …… 箭头函数 顾名思义 用箭头 “ => ” 定义函数 //es5的函数 var fn = function(num) { return n…
先来说下大致脚本引擎框架,此次采用如下,即运行C++代码启动程序,然后加载Lua脚本执行! 1.基础 Lua脚本中只能调用 int (*lua_CFunction) (lua_State *L) 这种类型的C/C++函数: 所有的C/C++函数如果要给Lua进行调用,只能用这样的函数来封装: 那么在C/C++中怎么获得Lua传递过来的参数? 通过操作Lua 虚拟机的栈 !下面我们来了解Lua堆栈! Lua C/C++互相调用应用: (1)Lua可以让程序员开发在Lua脚本中调用C/C++函数的接…
lua是扩展性非常良好的语言,虽然核心非常精简,但是用户可以依靠lua库来实现大部分工作.除此之外,lua还可以通过与C函数相互调用来扩展程序功能.在C中嵌入lua脚本既可以让用户在不重新编译代码的情况下修改lua代码更新程序,也可以给用户提供一个自由定制的接口,这种方法遵循了机制与策略分离的原则.在lua中调用C函数可以提高程序的运行效率.lua与C的相互调用在工程中相当实用,本文就来讲解lua与C相互调用的方法. Lua与C相互调用的首要问题是如何交换数据,lua API使用了一个抽象的栈与…
调用栈的英文名叫做Call Stack,大家或多或少是有听过的,但是对于js调用栈的工作方式以及如何在工作中利用这一特性,大部分人可能没有进行过更深入的研究,这块内容可以说对我们前端来说就是所谓的基础知识,咋一看好像用处并没有很大,但掌握好这个知识点,就可以让我们在以后可以走的更远,走的更快! 博客.前端积累文档.公众号.GitHub 目录 数据结构:栈 调用栈是什么?用来做什么? 调用栈的运行机制 调用栈优化内存 调用栈debug大法 数据结构:栈 栈是一种遵从后进先出(LIFO)原则的有序集…
最近在看<冴羽的博客>,讲真,确实受益匪浅,已经看了javascript 深入系列和专题系列的大部分文章,可是现在才想起来做笔记.所以虽然很多以前面试被问得一脸懵逼的问题都被“一语惊醒梦中人”过,注意这里我说的是“过”.是的,这些知道点,当时看的时候跟着大佬的思维,确实当时感觉“哦~ 原来是这样”,但是,看了下篇把上篇的知识忘了还是让我感觉自己太挫了. 于是,决定写点笔记来加深一点印象吧! 今天看到了“javascript专题之递归” (https://github.com/mqyqingfe…
函数参数的默认值 function log(x, y) { y = y || 'world' console.log(x + ' ' + y); } log('hello') // hello world log('hello','China') // hello China log('hello', '') // hello world /* * 如果 y 没有赋值,指定默认值为world // log('hello') // hello world * 如果 y 有赋值,指定赋值 log('…
1. Lua 调用OC 先看例子: hello.lua: -- 点击回调函数 local function notifymenuCallbackTest() local luaoc = require('luaoc') local ok, ret = luaoc.callStaticMethod("RemoteRequestRouter", "notifyWatch", {params1 = "NOTIFICATION_TO_HOME"}) en…
前面的话 第一次接触Lua是因为Unity游戏中需要热更,但是一直没搞懂Lua是怎么嵌入到别的语言中执行的,如何互相调用的.这次打算好好了解一下C跟lua是如何交互的 那么如何使用Lua语言? lua是c语言编写的,而且开源.可以在https://www.lua.org官网上下载Lua的源码,然后尝试编译它!是不是跟我一样好激动,一直用集成环境,写上层语言,今天居然要碰编译了!!~ 可怎么编译呢? 让我们召唤出编译神器:gcc![GNU编译器套件(GNU Compiler Collection)…
int main1(int argc, const char * argv[]) { lua_State* L = luaL_newstate();//创建栈 luaopen_base(L); luaopen_io(L);//打开lua base,io两个库 int ret = luaL_loadfile(L,"tlua.lua");//加载tlua.lua文件 //成功后会返回0,反之返回非0:同时错误信息放到栈顶 ){ printf("load file error %s…
这篇笔记主要集中学习一下uLua和Unity3D之间相互调用的方法,我们导入了uLua之后,现在会弹出一个类似学习屏幕的东西,如下: 先赞一个! Unity3D调用Lua Unity3D调用Lua的方法还是比较简单的,所以先说这个,由于这部分在学习笔记(一)中已经说的挺多的了,更多的内容点击这里回去看,所以这里我们就来看一个简单的示例即可: using LuaInterface; using UnityEngine; public class UnityCallLua : MonoBehavio…
最近在做一些奇怪的东西,需要Java应用能够接受用户提交的脚本并执行,网络部分我选择了NanoHTTPD提供基本的HTTP服务器支持,并在Java能承载的许多脚本语言中选择了很久,比如Rhino,Jython和JRuby之类,但它们都太过庞大,并且很难实现沙盒保护服务器环境.最后我的目光投向了Lua,那个被称为粘合剂的语言.遇到的第一个难题是选择所使用的库,纯Java实现的Lua解释器有很多,什么LuaJ,LuaJava,kahlua,还有不知名的mochalua,jill等等(好多好多),其中…
知识点: LuaInterface作用是用来完成Lua与C#的相互调用. LuaInterface核心库:1.luainterface.dll 用于C#读取lua(放在bin目录同级) 2.luanet.dll          用于lua读取C#(放在bin/debug目录下) 写C#脚本时如用到lua,则将luainterface.dll 和luanet.dll 导入工程,同时引用 using luainterface.dll;  这样就直接可以引用 Lua   xt =new Lua();…
本文主要讲如何完成lua和object-c的相互调用.       lua是一种脚本语言,可以方便的移植到各种宿主语言中,并且可以支持热更新,在游戏开发中也能当做主要的语言来编写游戏的逻辑,但是要接入第三方(例如支付宝等)时需要在不同的平台上(比如Android和ios)分别接入,这是就需要oc和lua完成通信   首先cocos2d 对oc和lua调用进行了封装,这就更有利于我们调用 cocos/cocos2d/luaoc   函数原型: -- 调用Objective-C类的接口. -- @f…
转自http://www.cnblogs.com/SkyD/archive/2011/09/01/2161502.html 引言 之前一直头痛于没有办法在多个程序中共享资源,用作公共类库的方法也是使用的导出jar再导入的办法,现在终于初步搞明白了,可算解脱了~,分享出来. 建立公共库 首先建立公共库的Android项目,名为MyCoreLib: 完成后在左侧包浏览器里右键点选我们新建的这个项目,选择Properties项: 左侧选择Android分类,右侧勾选Is Library选项: 完成后在…
lua编程中,我们经常也会遇到函数的声明定义和调用. [1]lua中函数定义与调用的方法 lua有两种函数定义和调用的方法(本质都是用属性,方式不同而已): (1)点号形式 (2)冒号形式 两种方法的联系: (1)相同点:本质都是用属性方式 (2)不同点:用冒号形式定义的函数默认会有一个参数self.self实质指向表本身(类似于C++中的this). [2]两种方法的定义调用实例对比 综上可知,两种方式会有四种组合需求: (1)点号定义 && 点号访问 } function _M.set…
转自:https://segmentfault.com/a/1190000004018047 这两天搜了下JS递归的相关文章, 觉得这篇文章很不错, 就顺手翻译了下,也算给自己做个笔记,题目是我自己加的.原文很长,写得也很详尽,这里并非逐字翻译, 而是作者所讲的主要概念加上我自己的一些理解,本文中解决方案的实际意义并不是特别大,但算法的逻辑挺有意思,不过也略抽象,理解需要花点时间(囧,估计我太闲了) 文中的用例…
(一) 首要概念要理清: 1. 在lua中,函数是一种"第一类值",他们具有特定的词法域."第一类值"表示在lua中函数与其他传统类型的值(例如数字和字符串)具有相同的权利. 2. 函数可以存储到变量中(无论全局变量还是局部变量)或table中,可以作为实参传递给其他函数,还是作为其他函数的返回值; 3. "词法域"是指:一个函数可以嵌套在另一个函数中,内部的函数可以访问外部函数中的变量; 一个语言如果支持闭包,那么通常都会具有第2点和第3点的特…
上一篇编辑编辑着,发现,缩进出了问题.作为一个不是强迫症的人,实在是忍受不了同一级内容不同缩进方式的槽点,于是重开一篇吧.(万幸,这样的文章也只有我自己看.) 第四 基本语法 赋值语句,Lua可以对多个变量同时赋值,变量列表和值列表的各个元素用逗号分开,赋值语句右边的值会依次赋给左边的变量. a, b = , *x <--> a=; b=*x 遇到赋值语句Lua会先计算右边所有的值然后再执行赋值操作,所以我们可以这样进行交换变量的值: x, y = y, x -- swap 'x' for '…