`
量产型人型自走炮
  • 浏览: 8295 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论
阅读更多
恩这个我知道
举个例子Enumerable#find
def find
 for i in 0...size
  value = self[i] 
  return value if yield(value)#我怎么确定这个return具体跳到哪里
 end
return nil 

分享到:
评论
25 楼 RednaxelaFX 2009-04-15  
night_stalker 写道
嗯,我想RX的意思就是跳出包着它的 def ~ (lambda 可以看做不写 def 的 def……)我觉得,lambda 和 Proc/block 的行为差异是因为:
  • lambda 一般是作为 object 传送
  • 而 Proc.new/block 一般是吊尾用的
不管怎样,不写 return 它们就很乖了。

嗯我说得不清楚……嘛,The Ruby Programming Language里讲解iterator的那段特别容易理解,请读一下那个。Programming Ruby扔了吧 =v=

我应该这么说,def...end和lambda {}或者->{}里的return都是返回到它们的调用者的,至于作为block/iterator的Proc里的return,你就把它们看作是它们所在的def...end或者lambda里的return就行了;Ruby里的block/iterator常是配合自定义控制结构来使用的。
24 楼 量产型人型自走炮 2009-04-15  
修正一下理解
只要写了return 除了lambda 总是直接跳出定义他的块所在的具名方法
全局域里面定义的块如果写了return在别的地方调用就肯定出错

这样对吗?
23 楼 night_stalker 2009-04-15  
RednaxelaFX 写道

第二句不对,非lambda的Proc里的return总是返回到return所在的具名方法的外面;你的说法比较含糊……

嗯,我想RX的意思就是跳出包着它的 def ~ (lambda 可以看做不写 def 的 def……)

我觉得,lambda 和 Proc/block 的行为差异是因为:

  • lambda 一般是作为 object 传送
  • 而 Proc.new/block 一般是吊尾用的


不管怎样,不写 return 它们就很乖了。
22 楼 量产型人型自走炮 2009-04-15  
RednaxelaFX 写道

量产型人型自走炮 写道不写return和lambda作为本地
proc里的return返回直接调用或定义它的函数
这么理解没错吧?Mina~ domo arigato gozaimasu
第一句我不太肯定我的理解跟你的理解是否相同……
第二句不对,非lambda的Proc里的return总是返回到return所在的具名方法的外面;你的说法比较含糊……

总是返回定义它的位置?
那在全局域调用定义的块用了return肯定会出错?
21 楼 RednaxelaFX 2009-04-15  
量产型人型自走炮 写道
咦,这里不是find调用了这个block吗?怎么会作为foo的返回呢?

你看前面我和night_stalker老兄都一直在说是return定义的那个具名方法,不是通过yield或者Proc#call来调用block的方法……
20 楼 量产型人型自走炮 2009-04-15  
引用

不,这是在“全局”作用域里,没有外围函数可返回了……于是就糟糕了。
def foo
  [1, 2, 3].find {|i| return i % 2 == 0 }
end
puts foo


咦,这里不是find调用了这个block吗?怎么会作为foo的返回呢?
19 楼 RednaxelaFX 2009-04-15  
量产型人型自走炮 写道
不写return和lambda作为本地
proc里的return返回直接调用或定义它的函数
这么理解没错吧?Mina~ domo arigato gozaimasu

第一句我不太肯定我的理解跟你的理解是否相同……
第二句不对,非lambda的Proc里的return总是返回到return所在的具名方法的外面;你的说法比较含糊……
18 楼 量产型人型自走炮 2009-04-15  
不写return和lambda作为本地
proc里的return返回直接调用或定义它的函数
这么理解没错吧?
Mina~ domo arigato gozaimasu
17 楼 RednaxelaFX 2009-04-15  
RednaxelaFX 写道

量产型人型自走炮 写道
异常的原因是非本地跳转?这里block里面的return不是作为find的返回吗?不,这是在“全局”作用域里,没有外围函数可返回了……于是就糟糕了。

你要明白这个:
def foo
  [1, 2, 3].find {|i| return i % 2 == 0 }
end

puts foo

与这个:
[1, 2, 3].find {|i| return i % 2 == 0 }

最大的不同就在于return的外面有没有具名方法
16 楼 night_stalker 2009-04-15  
量产型人型自走炮 写道

异常的原因是非本地跳转?这里block里面的return不是作为find的返回吗?


这里是 main 的定义,而不是 find 的定义~
irb(main):016:0> self
=> main
15 楼 量产型人型自走炮 2009-04-15  
哦 返回Bool值了= =这个都有检查啊
14 楼 RednaxelaFX 2009-04-15  
量产型人型自走炮 写道
异常的原因是非本地跳转?这里block里面的return不是作为find的返回吗?

不,这是在“全局”作用域里,没有外围函数可返回了……于是就糟糕了。
13 楼 量产型人型自走炮 2009-04-15  
irb(main):001:0> l = -> i { return i % 2 == 0 }
=> #<Proc:0x1a47c38@(irb):1 (lambda)>
irb(main):002:0> [1, 2, 3].find l
=> #<Enumerator:0x1a45294>
irb(main):003:0> [1, 2, 3].find &l
=> 2
irb(main):004:0> [1, 2, 3].find {|i| return i % 2 == 0 }
LocalJumpError: unexpected return
        from (irb):4:in `block in irb_binding'
        from (irb):4:in `each'
        from (irb):4:in `find'
        from (irb):4
        from E:/build_area/ruby191/bin/irb.bat:20:in `<main>'


异常的原因是非本地跳转?这里block里面的return不是作为find的返回吗?
12 楼 RednaxelaFX 2009-04-15  
量产型人型自走炮 写道
predicate 是对Proc对象的引用吧?那么这里既然不跳出的话 是不是retVal返回的是最后一个偶数?

你说的没错。predicate是一个具有lambda语义的Proc对象,Proc#[]是Proc#call的简写。这里返回的是最后一个偶数。
11 楼 RednaxelaFX 2009-04-15  
上面那个是Ruby 1.9.1里的,而下面用Ruby 1.8.6你会看到行为的差异:
irb(main):001:0> l = lambda {|i| return i % 2 == 0 }
=> #<Proc:0x03528b60@(irb):1>
irb(main):002:0> [1, 2, 3].find l
LocalJumpError: no block given
        from (irb):2:in `find'
        from (irb):2:in `each'
        from (irb):2:in `find'
        from (irb):2
irb(main):003:0> [1, 2, 3].find &l
LocalJumpError: unexpected return
        from (irb):1
        from (irb):3:in `find'
        from (irb):3:in `each'
        from (irb):3:in `find'
        from (irb):3
        from :0
irb(main):004:0> [1, 2, 3].find {|i| return i % 2 == 0 }
LocalJumpError: unexpected return
        from (irb):4
        from (irb):4:in `find'
        from (irb):4:in `each'
        from (irb):4:in `find'
        from (irb):4
        from :0

这里,&后的lambda还是当作普通的block了,所以一样出现了non-local return的问题。Ruby 1.9修改过这个行为……

总之在Ruby里没事别写return是个好习惯 XD
10 楼 量产型人型自走炮 2009-04-15  
Blog引用好糟糕= =
9 楼 量产型人型自走炮 2009-04-15  
RednaxelaFX 写道

你看这个
Ruby代码 module&nbsp;MyEnumerable&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;myfind(predicate)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retVal&nbsp;=&nbsp;nil&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block&nbsp;=&nbsp;lambda&nbsp;{|e|&nbsp;retVal&nbsp;=&nbsp;e&nbsp;if&nbsp;predicate[e]&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.myeach&nbsp;block&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retVal&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;&nbsp;end&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;Foo&nbsp;&nbsp;&nbsp;&nbsp;include&nbsp;MyEnumerable&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;myeach(block)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1..3).each&nbsp;{|i|&nbsp;block[i]&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;&nbsp;end&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;test&nbsp;&nbsp;&nbsp;&nbsp;foo&nbsp;=&nbsp;Foo.new&nbsp;&nbsp;&nbsp;&nbsp;val&nbsp;=&nbsp;foo.myfind&nbsp;lambda&nbsp;{|i|&nbsp;return&nbsp;i&nbsp;%&nbsp;2&nbsp;==&nbsp;0&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;val&nbsp;&nbsp;end&nbsp;&nbsp;&nbsp;&nbsp;test&nbsp;&nbsp;module MyEnumerable
  def myfind(predicate)
    retVal = nil
    block = lambda {|e| retVal = e if predicate[e] }
    self.myeach block
    retVal
  end
end

class Foo
  include MyEnumerable
  def myeach(block)
    (1..3).each {|i| block[i] }
  end
end

def test
  foo = Foo.new
  val = foo.myfind lambda {|i| return i % 2 == 0 }
  puts val
end

test

predicate 是对Proc对象的引用吧?
那么这里既然不跳出的话 是不是retVal返回的是最后一个偶数?

8 楼 RednaxelaFX 2009-04-15  
lambda和block都是Proc对象这点或许是一个巨容易让初学者混乱的地方……
Ruby 1.9里有Proc#lambda?来判断一个Proc对象是不是lambda。不过如果你是用yield来调用的话,被调用的肯定是block而不是lambda……看这个:
irb(main):001:0> l = -> i { return i % 2 == 0 }
=> #<Proc:0x1a47c38@(irb):1 (lambda)>
irb(main):002:0> [1, 2, 3].find l
=> #<Enumerator:0x1a45294>
irb(main):003:0> [1, 2, 3].find &l
=> 2
irb(main):004:0> [1, 2, 3].find {|i| return i % 2 == 0 }
LocalJumpError: unexpected return
        from (irb):4:in `block in irb_binding'
        from (irb):4:in `each'
        from (irb):4:in `find'
        from (irb):4
        from E:/build_area/ruby191/bin/irb.bat:20:in `<main>'
7 楼 night_stalker 2009-04-15  
对了,在 lambda 里的 return 和 Proc.new 的 return 不一样。

因为 lambda 是匿名函数,而不是 block。
6 楼 RednaxelaFX 2009-04-15  
你看这个
module MyEnumerable
  def myfind(predicate)
    retVal = nil
    block = lambda {|e| retVal = e if predicate[e] }
    self.myeach block
    retVal
  end
end

class Foo
  include MyEnumerable
  def myeach(block)
    (1..3).each {|i| block[i] }
  end
end

def test
  foo = Foo.new
  val = foo.myfind lambda {|i| return i % 2 == 0 }
  puts val
end

test

诶写得好无聊,不过随便看看吧。
这里虽然test里出现了return,但因为这个return位于一个lambda里,所以是本地返回,所以在调用test的时候不会出现non-local return exception之类的错误。

即使是嵌套了多层的block,return照样是在哪个具名方法里定义就从那个方法返回,只要block不是lambda。像是:
def test
  loop do
    loop do
      loop do
        return '...'
      end
    end
  end
end

puts test

相关推荐

    如何在QQ上使用美图聊聊?.docx

    在较早的版本中,你可能会直接找到“图片”选项,但在2013年4.2.0版及以上的新版QQ中,必须通过“拍照”功能才能触发美图聊聊。 3. **选择美图聊聊**: 在选择拍照后,系统会弹出一个窗口,此时你需要选择“美图聊...

    安卓开发-百度推聊应用.zip.zip

    2. **即时通讯技术**:百度推聊应用可能使用了自定义的消息协议或者基于XMPP、MQTT等协议进行实时通信。 3. **数据存储**:可能使用SQLite数据库存储用户信息、聊天记录等数据,或者利用sharedPreferences存储轻量...

    百度推聊应用.zip

    【标题】"百度推聊应用.zip" 是一个包含Android源码的学习资源,它可能是百度公司某款聊天应用的源代码示例。通过分析这个压缩包,我们可以深入理解Android应用程序的开发流程,掌握核心组件和功能的实现。 【描述...

    Android应用源码之百度推聊应用.zip

    推聊应用可能使用SQLite来保存用户信息、聊天记录等。研究数据库相关的代码,可以学习到如何创建表、插入/查询数据,以及如何使用ContentProvider进行数据共享。 5. **网络通信**:为了实现实时聊天,应用可能采用...

    安卓Andriod源码——百度推聊应用.zip

    这意味着我们可以期待在这个压缩包中找到用Java或Kotlin编写的Android工程文件,包括Activity、Service、BroadcastReceiver等组件,以及与百度Push SDK相关的配置和接口调用。 【标签】:“安卓”、“android”、...

    应用源码之百度推聊应用.zip

    《深入剖析:百度推聊应用源码学习》 在Android开发领域,源码学习是提升技术能力的重要途径。本资源“应用源码之百度推聊应用.zip”为我们提供了一个宝贵的实践平台,它涵盖了JAVA ANDROID的相关知识,适合作为...

    Android高级应用源码-百度推聊应用.zip

    【标题】"Android高级应用源码-百度推聊应用.zip" 涉及的主要知识点是Android应用程序开发,尤其是使用百度推送服务(Baidu Push SDK)进行实时通讯的应用实践。这个压缩包包含的是一个完整的Android项目源码,可以...

    安卓Android源码——百度推聊应用.zip

    【压缩包子文件的文件名称】:“Baidu-Push-SDK-Android-L2-3.2.0”是百度推送服务的SDK版本号,表示这个压缩包内包含了特定版本(L2,可能是某个特定功能的代号,3.2.0是具体的版本号)的Android版百度Push SDK。...

    QQ轻聊版7.3正式版发布.docx

    6. **与普通版共存**:轻聊版与普通版QQ可以同时存在于同一台电脑上,用户可以根据不同场景切换使用,满足多样化的使用需求。 7. **好友列表和聊天界面**:好友列表清晰明了,每个联系人的信息简洁直观;聊天界面则...

    QQ轻聊版好不好用.docx

    QQ轻聊版是一款针对PC用户推出的精简版即时通讯软件,旨在提供更为清爽、高效的聊天体验。相较于标准版QQ,轻聊版的核心特点是无广告、无插件,减少了潜在的骚扰与捆绑,使得用户能够专注于沟通本身。 首先,轻聊版...

    【JavaScript源代码】Vue在H5 项目中使用融云进行实时个人单聊通讯.docx

    在H5项目中集成实时个人单聊通讯功能,可以借助第三方服务如融云(RongCloud)。融云提供了一套API和服务,使得开发者能够方便地实现实时通信功能,包括聊天、群组聊天等。以下是将融云集成到Vue.js项目中的详细步骤...

    百度推聊应用.zip项目安卓应用源码下载

    在百度推聊应用中,你将看到如何使用这些组件来构建一个完整的应用,例如,Activity用于用户界面交互,Service处理后台通讯任务,BroadcastReceiver接收系统或自定义广播事件。 2. **网络通信**:即时通讯的核心是...

    ewebeditor v5.5 for ASP 戒聊修改版.rar

    考虑到“戒聊修改版”的特性,开发者在使用时还需要关注安全问题,如防止XSS攻击,以及优化性能,如减少不必要的网络请求,优化图片上传和处理流程,确保编辑器在保持功能的同时,也能高效稳定地运行。 综上所述,...

    QQ热聊怎么用.docx

    以下是关于如何使用QQ热聊的详细步骤和相关知识点: 1. **开启热聊功能**: - 首先,确保您的手机已经安装了最新版本的QQ应用程序,并且已经登录了您的QQ账号。 - 在QQ主界面,通常位于底部的导航栏,找到并点击...

    qq热聊怎么创建.docx

    请注意,虽然系统可能会提示在WiFi环境下使用,但实际在移动数据下也能创建和参与热聊。 4. **创建热聊** 要创建自己的热聊,你需要点击“创建热聊”按钮(如果该功能可见)。按照提示设置热聊的主题、简介,还...

    百度推聊.zip

    《深入剖析Android源码:以“百度推聊”为例》 在移动开发领域,Android操作系统以其开源、自由的特性,吸引了无数开发者投身其中。对于有志于提升Android开发技能的程序员来说,理解并掌握Android源码是至关重要的...

    QQ轻聊版forWindows体验评测.docx

    2. 界面设计:轻聊版取消了换肤功能,用户只能使用默认的水蓝色主题,但保留了Qzone、邮箱和天气等基础信息显示。界面上,轻聊版相比传统版本进行了大幅度精简,使得整体布局更为清爽。 3. 功能裁剪:核心业务方面...

    ewebeditor v5.5 for ASP 戒聊修改版.RAR

    《ewebeditor v5.5 for ASP 戒聊修改版》是一款专为ASP平台设计的网页编辑器,它主要用于在Web应用中提供便捷的富文本编辑功能。此修改版是针对ewebeditor v5.5版本进行了一定的优化和调整,以适应更严格的聊天环境...

Global site tag (gtag.js) - Google Analytics