首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带电流的呼叫-延续

带电流的呼叫-延续
EN

Stack Overflow用户
提问于 2012-05-16 09:21:25
回答 2查看 2.8K关注 0票数 3

我开始熟悉Ruby,并遇到了一个以前从未见过的函数-- callcc

我已经理解了一些关于它的一般概念,但是当我试图写一个例子时,我得到了意想不到的结果。

代码语言:javascript
复制
require 'continuation'
def callcc_func
  i = 0
  while true
    c = nil
    callcc {|x| c = x}
    i += 1
    puts i    
    return c if (i % 3) == 0
  end
end

c = callcc_func()
puts
callcc_func.call

结果是一个没完没了的循环。为什么?

我早就料到:

代码语言:javascript
复制
# for `c = callcc_func()` line
1
2
3

# callcc_func.call
4
5
6
#end here because of `return c if (i % 3) == 0`

附注:

对不起,我的英语和谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-16 10:04:44

call-with-current-continuation (通常缩写为call/cc )起源于Scheme,因此,如果您想了解更多有关它的信息,Scheme是一个很好的起点:

  • 在球拍文档中调用/抄送
  • 呼叫/抄送维基百科

至于你的Ruby问题:看看这篇博文标题延续与红宝石,它实现了一些与你想要做的非常相似的东西。你会在那里找到一个解释:

作为一个由主ruby解释器运行的脚本文件,这将在它捕获程序的控制状态时和在什么地方被调用时循环它,这包括返回延续,然后再调用它。

票数 1
EN

Stack Overflow用户

发布于 2014-07-21 13:56:56

这个答案有点晚了,但也许有人会感兴趣。

只需将代码的最后一行更改为:

代码语言:javascript
复制
c.call

这个特性的应用之一是制造生成器。下面是示例随机数生成器(取自数字食谱的常量):

代码语言:javascript
复制
def randomLCG(a,m,c,seed)
    initialized = false
    while true
        callcc {|x| $cc = x}
        if not initialized
            initialized = true
            return
        end
        seed = (a*seed + c) % m;
        return seed
    end
end

和用法:

代码语言:javascript
复制
> randomLCG( 1664525, 2147483647 , 1013904223, 107 )
 => nil 
> $cc.call
 => 1192008398 
> $cc.call
 => 2079128816 
> $cc.call
 => 667419302 

在Python中,我们可能会使用关键字yield来实现相同的目标(请注意,在Ruby关键字yield中所做的事情不同):

代码语言:javascript
复制
def randLCG (a , m , c , seed):
    while True:
        seed = ( a∗seed + c ) % m
        yield seed

用法:

代码语言:javascript
复制
>>> random = randLCG ( 1664525 , 2147483647 , 1013904223, 107 ) 
>>> random
<generator object randLCG at 0x7fdc790f70a0>
>>> random.next()
1192008398
>>> random.next()
2079128816
>>> random.next()
667419302

在Ruby中,您可以使用闭包来解决这个问题,这样您的程序就会更短:

代码语言:javascript
复制
require 'continuation'

def rand(a, m, c, seed)
    return lambda{ seed = (a*seed + c) % m; return seed }
end

c = rand( 1664525, 2147483647 , 1013904223, 107 )
c.call
c.call

我想到的第二个用法是实现mutual recursions

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10615536

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档