- 浏览: 3053073 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
在读Programming Ruby,突然想起以前在别人的blog上回过的一帖,顺带再回忆一下在自己blog上也记下来。
先看两个例子:
testClosure.cs:
testClosure.rb:
在上面的两段代码里,可以看到C#与Ruby有很相似的行为——这是因为C#中的delegate和Ruby中的block都是闭包(closure),所以它们可以“记忆”不在当前作用域内的变量(或者说非局部变量)。但闭包所记忆的并不一定是值,而可能是引用;在C#与Ruby中的闭包都是记住引用的,而像纯函数式语言则是记住值(其实没区别,纯函数式语言里的“变量”的值改变不了)。
既然C#和Ruby的闭包都是记引用,那为什么上面每组测试的前一个与后一个看起来行为不一样?
其实每组测试的前后两部分正好说明它们的本质是一样的。闭包的概念与静态作用域是紧密相关的。在C#的测试中,循环的控制变量i作用域覆盖整个循环过程;或者说整个循环过程使用到的i都是同一个i;前后两部分测试的结果不一样,是因为前一个测试里闭包所捕获的是只在一次循环里有效的j,每一轮循环中的j都不是“同一个”j;后一个测试的闭包捕获的是整个循环过程都有效的i,每一轮循环中的i都是同一个i,所以后续循环轮次中对i的改变都会影响到闭包所捕获的值。
Ruby方面同理。在Ruby 1.8.x中,与each迭代器关联的block里的变量是局部变量,每次each中使用yield来调用block时,block都会创建新的局部变量。而for与each的区别就是在循环变量的作用域上:for被展开后,先定义了一个局部变量,然后再调用each迭代器。
印象中上个月还是什么时候在经过别人的blog时见到过对Ruby的for的讨论,正好今天读到Programming Ruby时也看到了这介绍,记下。
不过在Ruby 1.9里,block的作用域有所改变。像这样:
(这消息来自Matz on Ruby 1.9)
我对“非常”这点无法认同……函数里无法定义函数是C/C++/Java的痛,或者说是出于设计考虑而不允许这点。
怎么说呢,如果只是用C/C++的话,不知道闭包是啥也没关系,完全不影响生活,反正想用也用不了。
先看两个例子:
testClosure.cs:
using System; using System.Collections.Generic; sealed class TestClosure { static void Main(string[] args) { var actions = new List<Action>(); for (int i = 0; i < 3; ++i) { int j = i; actions.Add(() => Console.WriteLine(j)); } foreach (var a in actions) { a(); } // Output: // 0 // 1 // 2 //////////////////////////////////////////////////// actions = new List<Action>(); for (int i = 0; i < 3; ++i) { actions.Add(() => Console.WriteLine(i)); } foreach (var a in actions) { a(); } // Output: // 3 // 3 // 3 } }
testClosure.rb:
procs = [] (1..3).each do |i| procs << lambda { puts i } end procs.each { |p| p.call } # Output: # 1 # 2 # 3 ############################################### procs = [] for j in (1..3) do procs << lambda { puts j } end procs.each { |p| p.call } # Output: # 3 # 3 # 3
在上面的两段代码里,可以看到C#与Ruby有很相似的行为——这是因为C#中的delegate和Ruby中的block都是闭包(closure),所以它们可以“记忆”不在当前作用域内的变量(或者说非局部变量)。但闭包所记忆的并不一定是值,而可能是引用;在C#与Ruby中的闭包都是记住引用的,而像纯函数式语言则是记住值(其实没区别,纯函数式语言里的“变量”的值改变不了)。
既然C#和Ruby的闭包都是记引用,那为什么上面每组测试的前一个与后一个看起来行为不一样?
其实每组测试的前后两部分正好说明它们的本质是一样的。闭包的概念与静态作用域是紧密相关的。在C#的测试中,循环的控制变量i作用域覆盖整个循环过程;或者说整个循环过程使用到的i都是同一个i;前后两部分测试的结果不一样,是因为前一个测试里闭包所捕获的是只在一次循环里有效的j,每一轮循环中的j都不是“同一个”j;后一个测试的闭包捕获的是整个循环过程都有效的i,每一轮循环中的i都是同一个i,所以后续循环轮次中对i的改变都会影响到闭包所捕获的值。
Ruby方面同理。在Ruby 1.8.x中,与each迭代器关联的block里的变量是局部变量,每次each中使用yield来调用block时,block都会创建新的局部变量。而for与each的区别就是在循环变量的作用域上:for被展开后,先定义了一个局部变量,然后再调用each迭代器。
印象中上个月还是什么时候在经过别人的blog时见到过对Ruby的for的讨论,正好今天读到Programming Ruby时也看到了这介绍,记下。
不过在Ruby 1.9里,block的作用域有所改变。像这样:
x = 15 (1..5).each do |x| puts x end puts x # -> 15
(这消息来自Matz on Ruby 1.9)
评论
5 楼
lwwin
2008-03-31
米事的嗯,偶总有时间来玩的-v-+
考试加油>o<!!!
考试加油>o<!!!
4 楼
RednaxelaFX
2008-03-31
下次……下次画几幅图来解释应该会比较清楚。这两天考试忙……
3 楼
lwwin
2008-03-31
不要回避啊,
偶当然知道没这东西了,但是还是要问啊,反正不知道就是不知道XD
于是FX大又要麻烦你了=v=|
偶当然知道没这东西了,但是还是要问啊,反正不知道就是不知道XD
于是FX大又要麻烦你了=v=|
2 楼
RednaxelaFX
2008-03-30
lwwin 写道
每次你说closure的时候总是用到函数里面定义函数这种非常的定义
我对“非常”这点无法认同……函数里无法定义函数是C/C++/Java的痛,或者说是出于设计考虑而不允许这点。
怎么说呢,如果只是用C/C++的话,不知道闭包是啥也没关系,完全不影响生活,反正想用也用不了。
1 楼
lwwin
2008-03-29
closure这个概念真是不够形象……
偶总是不能够理解其中的概念
看了一些说明,跟没看一样,每次你说closure的时候总是用到函数里面定义函数这种非常的定义,弄了半天不知道怎么回事……
偶总是不能够理解其中的概念
看了一些说明,跟没看一样,每次你说closure的时候总是用到函数里面定义函数这种非常的定义,弄了半天不知道怎么回事……
发表评论
-
Sun JDK1.4.2_28有TieredCompilation
2014-05-12 08:48 0原来以前Sun的JDK 1.4.2 update 28就已经有 ... -
IBM JVM notes (2014 ver)
2014-05-11 07:16 0Sovereign JIT http://publib.bou ... -
Java 8的lambda表达式在OpenJDK8中的实现
2014-02-04 12:08 0三月份JDK8就要发布首发了,现在JDK8 release c ... -
基于LLVM实现VM的JIT的一些痛点
2014-01-07 17:25 0同事Philip Reames Sanjoy Das http ... -
tailcall notes
2013-12-27 07:42 0http://blogs.msdn.com/b/clrcode ... -
《自制编程语言》的一些笔记
2013-11-24 00:20 0http://kmaebashi.com/programmer ... -
字符串的一般封装方式的内存布局 (1): 元数据与字符串内容,整体还是分离?
2013-11-07 17:44 22409(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局 (0): 拿在手上的是什么
2013-11-04 18:22 21509(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局
2013-11-01 12:55 0(Disclaimer:未经许可请 ... -
关于string,内存布局,C++ std::string,CoW
2013-10-30 20:45 0(Disclaimer:未经许可请 ... -
Function.prototype.bind
2013-09-24 18:07 0polyfill http://stackoverflow. ... -
Java的instanceof是如何实现的
2013-09-22 16:57 0Java语言规范,Java SE 7版 http://docs ... -
struct做参数不能从寄存器传?
2013-08-28 23:33 0test test test struct Foo { i ... -
也谈类型: 数据, 类型, 标签
2013-08-18 01:59 0numeric tower http://en.wikiped ... -
SDCC 2012上做的JVM分享
2012-10-17 16:35 32662刚把在SDCC 2012做的JVM分享的演示稿上传了。 演示 ... -
运行时支持系统的“重量”
2012-10-12 16:08 0运行时支持系统的“重量” 好久没写博客了,可写的话题已经堆积 ... -
class?metaclass?meta-what?
2011-04-05 19:43 0http://en.wikipedia.org/wiki/Me ... -
“代码模式”与抽象
2010-10-28 15:21 0嗯,我是说“代码模式”,不是“设计模式”;这里指的是在给定的场 ... -
lvalue与rvalue
2010-09-03 00:40 0http://en.wikipedia.org/wiki/Va ... -
动态链接的“依据”
2010-02-09 09:54 0动态链接,意味着在生成的“东西”里留有符号信息,等到运行时再r ...
相关推荐
`lambda`创建的Proc对象在行为上与普通Proc对象有所不同,主要体现在两个方面: 1. 参数检查:`lambda`对参数的检查更为严格,如果传入的参数数量与定义不符,它会抛出错误。相比之下,普通的Proc对象会尝试适应...
然而,【部分内容】实际上是包含了一系列与多个IT主题相关的资源和学习材料的链接,包括Java、.Net技术、C#、C++、Python、Ruby、数据库管理系统、平面设计、Linux、PHP、UML、Linux系统管理、Linux shell编程、UNIX...
2. **作用域与闭包**: - JavaScript拥有独特的作用域机制——基于函数的作用域。闭包是函数和与其相关的引用环境的组合,允许函数访问并操作其定义时所在环境中的变量。这种能力在编写异步代码或处理事件驱动逻辑...
9. **闭包与匿名函数**:Boo支持闭包,即能够访问其自身作用域的函数,这对于实现回调和高阶函数非常有用。匿名函数(lambda表达式)则允许快速定义一次性使用的函数。 10. **单元测试**:Boo内建了对单元测试的...
例如,闭包和作用域的概念就是通过特定的数据结构和算法来实现的。 ##### 5.2 引擎如何处理原型继承 JavaScript引擎通过内部数据结构来维护对象之间的继承关系。当一个对象试图访问一个不存在的属性或方法时,引擎...
在CodeWars中,你可以通过解决Kata来学习JavaScript的核心特性,如变量、数据类型(包括基本类型和引用类型)、作用域、闭包、原型链、异步编程(回调函数、Promise、async/await)等。 此外,CodeWars还强调代码的...