PHP、Lua中的 尾调用】的更多相关文章

在程序设计中,递归(Recursion)是一个很常见的概念,合理使用递归,可以提升代码的可读性,但同时也可能会带来一些问题. 下面以阶乘(Factorial)为例来说明一下递归的用法,实现语言是PHP: <?php function factorial($n) { if ($n == 0) { return 1; } return factorial($n - 1) * $n; } var_dump(factorial(100)); ?> 如果安装了XDebug的话,可能会遇到如下错误: Fa…
尾调用(Tail Call) 尾调用是函数式编程里比较重要的一个概念,它的意思是在函数的执行过程中,如果最后一个动作是一个函数的调用,即这个调用的返回值被当前函数直接返回,则称为尾调用,如下所示: function f(x) { return g(x) } 在 f 函数中,最后一步操作是调用 g 函数,并且调用 g 函数的返回值被 f 函数直接返回,这就是尾调用.而下面这个栗子就不是尾调用: function f(x) { return 1 + g(x) } 原因是它的最后一步操作是将 g 函数…
文章来源自:http://www.zhufengpeixun.com/qianduanjishuziliao/javaScriptzhuanti/2017-08-08/768.html JavaScript 中的尾调用优化(tail call optimization) 我在学习尾调用优化的过程中,有两个误解: 第一个是,我们一谈优化,经常说时间的优化.但是尾调用优化却主要是指空间的优化. 第二个是,既然尾调用优化是在 es6 中支持的,那么可能又要学新的语法了.然而,尾调用优化并不需要新的语法…
Lua支持“尾调用消除(tail-call elimination)”.尾调用(tail call):当一个函数调用是另一个函数的最后一个动作时,该调用才算是一条“尾调用”.例如,下面的代码就是一条“尾调用”: function f (x) return g(x) end 也就是说,当f调用完g之后就再无其他事情可做了.因此在这种情况下,程序就不需要返回那个“尾调用”所在的函数了.所以在“尾调用”之后,程序也不需要保存任何关于该函数的栈(stack)信息了.当g返回时,执行控制权可以直接返回到调…
<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.jb51.net/article/56690.htm Lua 中 metatable 是一个普通的 table,但其主要有以下几个功能: 1.定义算术操作符和关系操作符的行为2.为 Lua 函数库提供支持3.控制对 table 的访问 Metatables 定义操作符行为 Metatable 能够被用于定义算术操作符和关系操作符的行为.例如:Lua 尝试对两个 table 进行加操作时,它会按顺序检查这两个 table 中是否有一个存在 metatable 并且这个…
我非常想把一些非必需的信息以CSV表的格式保存到客户端,以减少和服务器的通讯,降低压力.于是写了这么一个. 但因为大家觉得这样的话,需要每次登陆时来检测同步这些数据,会减慢登陆速度,于是没有用到. 我觉得日后服务器压力增大了以后,可以这么使用. 总体上是两部分: 加密和读取. 1 加密 使用quick自带的pack_files命令加密CSV文件.在quick\bin\pack_files.bat 具体使用方法可进去查看sample. 启动程序时,告诉lua堆栈加密的密钥等. 具体代码如下 打包时…
最近在做一些奇怪的东西,需要Java应用能够接受用户提交的脚本并执行,网络部分我选择了NanoHTTPD提供基本的HTTP服务器支持,并在Java能承载的许多脚本语言中选择了很久,比如Rhino,Jython和JRuby之类,但它们都太过庞大,并且很难实现沙盒保护服务器环境.最后我的目光投向了Lua,那个被称为粘合剂的语言.遇到的第一个难题是选择所使用的库,纯Java实现的Lua解释器有很多,什么LuaJ,LuaJava,kahlua,还有不知名的mochalua,jill等等(好多好多),其中…
1.首先说下目的,为什么要这么做 ? 正式项目中,希望主程序尽量不做修改,于是使用C/C++完成功能的主干(即不需要经常变动的部分)用lua这类轻量级的解释性语言实现一些存在不确定性的功能逻辑:所以,程序功能如有问题,只需对lua脚本作出修改,而修改脚本的好处是简单高效,改完脚本后重新执行程序便能看到效果.  2.具体怎么做? 一般来说,C/C++调用lua接口或是数据交互,首先要做的是包含lua相关操作的头文件以及lua库相关的头文件,然后调用接口创建lua环境.用操作栈的规则和lua交互数据…
项目使用ulua,我神烦这个东西.lua单纯在lua环境使用还好,一旦要跟外界交互,各种月经不调就来了.要记住贼多的细节,你才能稍微处理好.一个破栈,pop来push去,位置一会在-1,一会在-3,21世纪已经过去五分之一了好吗,谁乐意像汇编一样操作?那十几个操作函数,愣是比正则表达式规则还难记,用完就忘.我发现lua心智负担完全跟简洁搭不上边,贼他娘重,实现个面向对象都乱七八糟.我学c++都没觉得有什么不爽的,就lua代码各种不乐意看,各种小tips在那里,什么meta,weak,_G,逼着你…
项目开发中一些常用的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…
Lua中“.”调用方法与“:”调用方法的区别:                                                                                                                         一.概述 学lua的时候有一个迷惑点,就是搞不清楚‘.’与‘:’调用方法的区别,今天很早就起来看了看一个大牛的视频讲解,才顿悟了:‘.’调用和‘:’实际是传递参数的个数不同而已,‘:’实际是一个语法糖. 二.演示…
目前项目,使用了Lua脚本,至于使用Lua的好处不再赘述了.于是对Tolua做了一些小小的学习,总结一下吧. 主要说一下如何在Lua中调用C++方法. Lua调用C++的桥梁,是tolua.tolua是什么,http://blog.csdn.net/killwd/article/details/1423923 这篇文章介绍的很详细. 我们需要手动做的,其实便是编写中间类,这个类被tolua直接使用,最终的目的是实现lua中对象方法和C++中对象方法的对应. LuaCocos2d.cpp 完成了所…
尾调用是指在函数return时直接将被调函数的返回值作为调用函数的返回值返回,尾调用在很多语言中都可以被编译器优化, 基本都是直接复用旧的执行栈, 不用再创建新的栈帧, 原理上其实也很简单, 因为尾调用在本质上看的话,是整个子过程调用的最后执行语句, 所以之前的栈帧的内容已经不再需要, 完全可以被复用.报错的回溯日记,因为旧的执行栈已经没了,所以报错日记只显示(tail call).一般调用栈的长度为1M到2M,保存了调用过程中的参数和相关环境,如果递归调用太长,就会溢出.尾调用就能解决递归函数…
lua中调用C++函数 我们产品中提供了很多lua-C API给用户在lua中调用,之前一直没用深究其实现原理,只是根据已有的代码在编码.显然这不是一个好的习惯,没用达到知其所以然的目的. 一.基本原理 将C++函数编译成动态链接库,然后在lua中require,通过下面的示例进行详解. #ifdef __cplusplus extern "C" { #endif #include<lua.h> #include<lualib.h> #include<la…
1 lua中函数作为表中元素时有三种定义方式 采用‘:’来定义,实际上隐藏了一个形参的声明,这个形参会截获调用函数时的第一个实参并把它赋值给self 2 调用方式,点号和冒号 functb:hello1()functb.hello2() 总结起来就是带:号调用表的函数时,会把表赋值给self,这样函数体里面可以直接使用self访问表的数据…
在上一篇文章 Unity3D热更新之LuaFramework篇[04]--自定义UI监听方法 中,我对LuaBehaviour脚本进行了扩展,添加了两个新的UI监听方法,也提到最好能单写一个脚本处理此事.本篇文章就来继续这个工作. 从Lua中调用C#代码 1.创建UI监听脚本 打开之前的工程,在Assets/LuaFrameworks/Scripts/Common下,创建一个UIEventEx.cs脚本,将LuaBehaviour.cs中的AddButtonClick以及AddInputFiel…
环境 windows8, cocos2d-x 3.0, 现在开始安装需要的一些其它包 1. 按README.mdown文档上面要求的, 下载在windows下要安装的东东, 主要就是python2.7.3, PyYAML-3.10.win32-py2.7, pyCheetah 这些东东在README.mdown上面都给好了连接, 直接下载就行了, 安装好python后, 在系统环境变量的PATH中设置python所在的目录2. 安装android-ndk-r9b, 下载地址:http://dl.…
前面的话 第一次接触Lua是因为Unity游戏中需要热更,但是一直没搞懂Lua是怎么嵌入到别的语言中执行的,如何互相调用的.这次打算好好了解一下C跟lua是如何交互的 那么如何使用Lua语言? lua是c语言编写的,而且开源.可以在https://www.lua.org官网上下载Lua的源码,然后尝试编译它!是不是跟我一样好激动,一直用集成环境,写上层语言,今天居然要碰编译了!!~ 可怎么编译呢? 让我们召唤出编译神器:gcc![GNU编译器套件(GNU Compiler Collection)…
在进行lua方法注册的时候, 大多数解决方案直接否定了泛型方法, 因为在lua侧难以表达出泛型, 以及lua的函数重载问题, 函数重载问题可以通过一些特殊方法解决, 而泛型问题是主要问题, 以Unity + Slua的情况来说 比如下面的类: public class Foo { public static void GetTypeName(System.Type type) { Debug.Log(type.Name); } public static void GetTypeName<T>…
在第一篇的01最小实现中,我们实现了一个断点调试的最小实现,在设置钩子函数时只加了line事件,显然这会对性能有很大的影响.而后来两篇02通用变量打印和03通用变量修改及调用栈回溯则是提供了一些辅助的调试接口,并没有对钩子函数进行修改. 我们本篇将在钩子中引入call和return事件的处理,尝试对性能进行优化. 源码已经上传Github,欢迎watch/star. 本博客已迁移至CatBro's Blog,那里是我自己搭建的个人博客,欢迎关注. 实现分析 当前的实现因为只加了line事件,执行…
在上一篇04优化钩子事件处理中,我们在钩子函数中引入了call和return事件的处理,对性能进行了优化. 细心的同学可能已经发现了,我们的hook函数中call事件和line都需要对整个断点表进行遍历,这其中其实是存在着一些冗余的.因为call事件只关心函数是否有断点,而line事件则只关心本函数内有哪些断点.所以我们可以想办法优化一下断点信息的数据结构,进一步提升性能. 源码已经上传Github,欢迎watch/star. 本博客已迁移至CatBro's Blog,那里是我自己搭建的个人博客…
基类:基类定义了所有对于派生类来说普通的属性和方法,派生类从基类继承所需的属性和方法,且在派生类中增加新的属性和方法. 继承:继承是C++语言的一种重要机制,它允许在已定义的类的基础上产生新类. lua基类和C++基类极为相似,但是lua中却没有继承这一说,更没有所谓的派生类.lua只能通过一种行为(元表)来模拟C++继承这一方法. 元表:lua中提供的元表是用于帮助lua数据变量完成某些非预定义功能的个性化行为,当它做某一种操作,然而self表中却没有定义实现这种操作的方法,那么为了实现这一操…
ok,前面准备给一个dll写wrapper,写了篇日志,看似写的比较明白了,但是其实有很多米有弄明白的.比如PIL中使用的element,key,tname,field这些,还是比较容易混淆的.今天正好搞搞清楚. 1.stack 这个应该不用多讲了,C和lua中的交互就是基于一个stack的,而且每次lua调用一个c函数,都是给分配一个新的stack.它的原型: typedef int (*lua_CFunction) (lua_State *L); stack中的基本单元在PIL中多成为ele…
{--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:包含…
lua 是一种脚步语言,语言本身并不具备面向对象的特性. 但是我们依然可以利用语言的特性,模拟出面向对象的特性. 面向对象的特性通常会具备:封装,继承,多态的特性,如何在lua中实现这些特性,最主要的就是利用了lua的table和metatable. table是一种强大的关联数组,它可以使用数字和字符串做key,而且可以使用点操作符访问table的元素,因此非常使用用于存储一个对象的属性: metatable依然可以认为是一种关联数组,但是元表的作用更加强大,主要是: 1.定义算术操作符和关系…
废话:好久没在这里写博客了...主要原因是我买了个域名hanxi.info并在github上搭建了个人博客... lua中默认是没有c中的const常量的,在csdn上找到了一个使用setmetatable.参考http://blog.csdn.net/xiaodan007/article/details/6668015.主要原理就是重载__index方法(相当于get方法)和__newindex方法(相当于set方法).但是他实现的是不支持表中有表的情况的. 下面是我修改后的代码: funct…
如果你看了LUA的文档,那么就应该很清楚LUA与C交互数据时都是用到LUA中所谓的stack.那么当我调用lua_open函数之后栈是什么样的呢?空的(luaopen_base等会往栈上加进一些东西).那么至于如何操作栈上的数据,我想官方文档上已经说得很清楚了,不过最初我对于栈的顺序有一些迷糊,所以就说说这个.现在假如我有如下的一段代码: 代码: lua_State* L = lua_open();lua_pushnumber( L, 211 );lua_pushnumber( L, 2222…
弱表(weak table)是一个很有意思的东西,像C++/Java等语言是没有的.弱表的定义是:A weak table is a table whose elements are weak references,元素为弱引用的表就叫弱表.有弱引用那么也就有强引用,有引用那么也就有非引用.我们先要厘这些基本概念:变量.值.类型.对象. (1)变量与值:Lua是一个dynamically typed language,也就是说在Lua中,变量没有类型,它可以是任何东西,而值有类型,所以Lua中没…
Lua中的协程和多线程很相似,每一个协程有自己的堆栈,自己的局部变量,可以通过yield-resume实现在协程间的切换.不同之处是:Lua协程是非抢占式的多线程,必须手动在不同的协程间切换,且同一时刻只能有一个协程在运行.并且Lua中的协程无法在外部将其停止,而且有可能导致程序阻塞. 协同程序(Coroutine): 三个状态:suspended(挂起,协同刚创建完成时或者yield之后).running(运行).dead(函数走完后的状态,这时候不能再重新resume). coroutine…