while TRUE + 在子环境中中断

Posted

技术标签:

【中文标题】while TRUE + 在子环境中中断【英文标题】:while TRUE + break in a sub-environment 【发布时间】:2016-07-11 00:04:09 【问题描述】:

我无法让while(TRUE) 循环工作。我认为这个例子解决了问题的症结:

l <- list(x = 5)

while (TRUE)
  with(l, if (x > 100) break else l$x <<- x + 5)

运行出错:

eval(expr, envir, enclos) 中的错误:

break/next 没有循环,跳转到顶层

奇怪的是,while 循环似乎已成功执行:

l
# $x
# [1] 105

看来问题是我在子环境中发送break 语句,因为以下内容按预期工作而没有错误:

x = 5

while(TRUE)
  if (x > 100) break else x <<- x+5

认为这只是环境问题,我也尝试将break 替换为eval(break, parent.env())eval(break, parent.frame()),但无济于事。

我怎样才能停止这个错误?


我想sessionInfo() 可能是相关的:

R version 3.2.4 (2016-03-10)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 14.04.3 LTS

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] readxl_0.1.0.9000 data.table_1.9.6  haven_0.2.0      

loaded via a namespace (and not attached):
[1] rsconnect_0.4.1.11 tools_3.2.4        Rcpp_0.12.1        chron_2.3-47      

【问题讨论】:

有理由使用with吗?为什么不只是if (l$x&gt;100) break else l$x&lt;-l$x+100 @nicola 问题的上下文略有不同;我选择这个来复制我认为是必需品的东西。也就是说,在我的实际使用中,break 是在对[.data.table 的调用中发送的 也许更好地解释上下文会有所帮助,因为这里很明显是环境问题:while(TRUE) with(l,break) 产生相同的错误。显然,with 产生了一个环境,R 不希望从中产生break R 的with 只是一个函数。所以你实际上是在这样做:while(TRUE) (function() break)()break 在内部函数范围内,而while 在外部函数范围内。 @AWebb 谢谢,我知道with-equals-function 位,麻烦在于找出确切评估break 的位置,因为while 正在自己工作环境 【参考方案1】:

@Vongo 建议的一个变体是使用environment() 捕获应该进行评估的环境,然后使用evalq() 在正确的位置评估break

l <- list(x = 5)
while (TRUE)
    env <- environment()
    with(l, if (x > 100) evalq(break, env) else l$x <<- x + 5)

这避免了解析文本字符串,因此看起来不那么老套。在捕获的环境env 中进行评估允许循环在 R 代码中的任何级别,而不仅仅是在 .GlobalEnv 中。这就像一个非本地跳转(又名 GOTO),这使得推理代码变得更加困难。

【讨论】:

还有evalq(break, parent.env(environment()))。如果break 被发送到错误的环境,我仍然不确定为什么原始代码不是无限循环。有什么原因吗? @MichaelChirico 最好明确 env= 而不是依赖调用堆栈的顺序进行发现,因为程序员可能会无意中更改调用堆栈。原始代码产生了一个错误,并且由于该错误,循环结束了。 哦,这很有道理。【参考方案2】:

也许我不明白这个问题的所有利害关系,但你可以试试:

l <- list(x = 5)
while (TRUE)
  with(l, if (x > 100) eval(parse(text="break"), envir=.GlobalEnv) else l$x <<- x + 5)

【讨论】:

抱歉,刚回来。我认为@Martin Morgan 解释了这种方法,甚至改进了它。赞一个!

以上是关于while TRUE + 在子环境中中断的主要内容,如果未能解决你的问题,请参考以下文章

使用while循环时未触发中断ISR

mysql while循环中断等效

while循环时非法中断语句

Windows API 中的不间断线程部分

stm32程序执行完main函数然后去干嘛了?之后的中断为何不能响应???

单片机中断结束后从哪main函数从头开始执行吗?还是回到while(1);那里??