for 循环中 ->(右箭头)和 <-(左箭头)的不同行为

Different behavior of -> (right-arrow) and <- (left arrow) on a for loop

,一个 for 循环 returns NULL(如文档所示):

x <- for(i in 1:3) {i+1}
x
# NULL

然而,使用右箭头赋值,似乎returns最后一个值:

for(i in 1:3) {i+1} -> x
x
# [1] 4

那个documentation doesn't comment on ->, and ,那个->好像是转成<-反正:

expression(1 -> x)
# expression(x <- 1)

所以我的问题是:

  1. 这是错误还是误解?
  2. 如果 -><- 的行为本应相同,那么在这种情况下,为什么它们会有所不同?

我认为这更像是一个解析问题。命令

for(i in 1:3) {i+1} -> x

实际上被解析为

for(i in 1:3) {
   x <- {i+1}
}

你可以在 lobstr 包的帮助下在 AST 中看到它

lobstr::ast(for(i in 1:3) {i+1} -> x)
o-`for` 
+-i 
+-o-`:` 
| +-1 
| \-3 
\-o-`<-` 
  +-x 
  \-o-`{` 
    \-o-`+` 
      +-i 
      \-1 

所以赋值是循环体的一部分。例如,您也可以 运行 这没有错误

for(i in 1:3) {i+1} ^2

或者看看你从这个表达式中得到了什么

for(i in 1:3) {i+1} + {print(i)}
# [1] 1
# [1] 2
# [1] 3

循环体表达式没有在第一个大括号结束时终止。它在行尾结束(或者你可以让它以 ; 结束,或者将它嵌套在代码块中)。这在任何方面都不是赋值运算符独有的。

所以这不是错误,只是语法有点混乱。你期待的看起来更像

{for(i in 1:3) {i+1}} -> x

仍然 returns NULL。