lambda的实现
来源:互联网 发布:网络社交的利与弊论文 编辑:程序博客网 时间:2024/06/07 03:00
一开始我并没打算在larva实现前面说的解析式和这篇要说的lambda,因为当时觉得解析式可以用循环来代替,lambda则可以用可调用对象代替,但后面发现还是做了比较好,毕竟这俩东西太方便了,如果没有的话代码写起来很啰嗦。其实碰到的第一个问题是列表解析式,因为我本来觉得,对我来说lambda使用的地方不是很多(虽然很多人喜欢用),不过在开始做列表解析式的时候,我忽然想到python中的map函数,如果用map配合lambda也是可以实现解析式的功能,所以先实现的反而是lambda,然而在做到一半的时候发现,预先设计的lambda语法配合map只能实现...for...in...的解析式,不能实现...for...in...if...,除非给map函数增加参数,所以又回过头做列表解析式,于是最后的结果是,列表、字典解析式和lambda都做了
语法方面,larva的lambda和python一样,不过在机制上做了一点修改。python的lambda是一个返回一个表达式值的匿名函数,和def没有什么区别,即:
lambda在两种语言中的重要区别可以用一个例子体现:
而类似的代码在larva下会打印出10个123,原因在于larva在生成lambda对象的时候不是关联到当前函数局部环境,而是对当前函数局部环境做了一个快照,即拷贝了一份保存到自己对象内部,如果要实现上述python的效果,可以改成这样:
之所以这么做,起源于之前在网上看到一些朋友关于这个问题的争议,究竟是关联环境好,还是拷贝环境好,似乎更多人觉得拷贝更直观一些,不过我没有研究其他语言中的lambda或闭包是怎么处理的
lambda的实现和前述的列表、字典解析式类似,对于代码中每个lambda,都对应一个类,这个类有内建的op_call方法,也就是函数调用运算“()”的重载实现,当然这个类是继承自LarObj的,所以:
语法方面,larva的lambda和python一样,不过在机制上做了一点修改。python的lambda是一个返回一个表达式值的匿名函数,和def没有什么区别,即:
f = lambda x : x + 1相当于
def f(x): return x + 1python中一切都是对象,所以这里的f也就是个普通变量,引用了一个函数对象,所以如果不是匿名地使用函数,用def代替lambda可读性可能还好些,这种机制虽然灵活,但有点太灵活了,如果忘了写函数的括号,语法上没错但是是另一个含义,比如我经常看到有人在关闭文件的时候写f.close,实际只是对close方法对象求值,没有实际关闭。考虑到这个问题,以及实际中函数本身作为对象的情况相对直接调用的情况少很多,larva规定函数、类、方法等不是对象,也就是不能作为单独表达式存在,如果要像一个对象一样用,就需要用lambda封装,比如:
g = lambda x : f(x)则调用g(x)就相当于f(x),只不过g是对象,而f不是,我觉得显式的语法更方便突出函数的非调用使用
lambda在两种语言中的重要区别可以用一个例子体现:
def main(): i = 123 f = lambda : i for i in range(10): print f()python中执行这段代码,会打印0到9,原因在于,这个lambda是一个闭包函数,它里面用到的这个i是引用main函数当前调用的局部变量环境,因此main函数中的i变化时,调用f返回的是main中i的值
而类似的代码在larva下会打印出10个123,原因在于larva在生成lambda对象的时候不是关联到当前函数局部环境,而是对当前函数局部环境做了一个快照,即拷贝了一份保存到自己对象内部,如果要实现上述python的效果,可以改成这样:
func main(): i = [123] f = lambda : i[0] for i[0] in range(10): print f()由于lambda保存局部环境快照时用的浅拷贝,所以用一个容器就做到了
之所以这么做,起源于之前在网上看到一些朋友关于这个问题的争议,究竟是关联环境好,还是拷贝环境好,似乎更多人觉得拷贝更直观一些,不过我没有研究其他语言中的lambda或闭包是怎么处理的
lambda的实现和前述的列表、字典解析式类似,对于代码中每个lambda,都对应一个类,这个类有内建的op_call方法,也就是函数调用运算“()”的重载实现,当然这个类是继承自LarObj的,所以:
f = lambda x : x + i就被实现为类似java代码:
f = new Lambda_0001(i);其中当前环境,也就是变量i的值在构造时传入,由lambda对象保存,这个lambda对象的实现类似如下代码:
class Lambda_0001 extends LarObj{ private LarObj m_i; Lambda_0001(LarObj i) { m_i = i; } public LarObj op_call(LarObj x) { return x.op_add(m_i); }}而如果lambda中出现全局变量和this/super等,处理方式也和列表解析式的实现一致,全局变量不做快照,按照每次调用时的实际值参与运算,而若在方法中使用lambda,将Lambda_XXXX类实现在对应外部类中,this/super的访问等于是java帮忙做了个快照了
0 0
- lambda的实现
- boost::lambda的实现模拟
- Lift ( lambda 的新实现 )
- Javascript Lambda的简单实现
- lambda表达式的底层实现
- lambda表达式的简单实现
- C++实现的lambda Y算子
- 一段PHP版本的lambda实现
- Java8 lambda表达式的实现探索
- C++ lambda表达式的编译器实现..
- keras Lambda自定义层实现数据的切片,Lambda传参数
- 使用Java8的Lambda实现的一个简单案例
- Java lambda 实现sort
- 一个使用TBB Lambda 表达式实现并行执行的例子
- C#基于Lambda递归的阶乘/累加实现
- python求素数的一句话代码 lambda实现
- C#利用lambda实现委托事件的挂接
- C#利用lambda实现委托事件的挂接
- 灼茁字滓抓左左抓资状总赚姿踪卓踪邹庄
- 删除svn 文件信息
- android 基础知识 :android Bitmap图片读取方法
- Activity四种加载模式
- 灼做追砖驻邹籽注转妆篆撞做纂座渍状左
- lambda的实现
- 新手嫁到,请多关照
- Androidpn 消息推送总结
- 谞卒谞妆姿注琢罪灼浊渍抓渍专兹椎祝拽
- 解决github push错误The requested URL returned error: 403 Forbidden while accessing
- JAVA ForEach循环使用及短板分析
- jQuery EasyUI — 按钮间的自定义竖线(分隔线)样式
- Android: Receiving Data from the Send Intent,将自己的app注册系统分享
- 如何使 iOS 中的各种控件的 Cancel 按钮变成中文