6.1 直接操作语言对象
Next: Substitutions,Previous: Computing on the language,Up: Computing on the language
6.1 直接操作语言对象
有三种语言对象可用于修改,调用,表达式和函数。基于这种认识,我们集中讨论调用对象。就是有时称之为“未求值表达式”(unevaluated expressions)的对象,尽管这个术语有点让人困惑。获得一个调用对象最直接的方法是把一个表达式参数赋给 quote 函数,如
> e1 <- quote(2 + 2)
> e2 <- quote(plot(x, y))
参数没有被求值,结果简单地解析为参数。对象 e1 和 e2 可以随后用eval求值,或简单地当作数据。这就很明显为什么 e2 对象的模式是 "call",因为它利用一些参数调用了函数 plot。但是 e1 实际上有和调用双参数的二元操作符+完全一样的结构。这个事实可以通过下面的例子更清晰地展示
> quote("+"(2, 2))
2 + 2
调用对象的分量可以通过列表类似的语法访问,并且可能用as.list 和as.call 与列表进行相互转换
> e2[[1]]
plot
> e2[[2]]
x
> e2[[3]]
y
在使用关键字参数匹配时,关键字可以作为列表的标签:
> e3 <- quote(plot(x = age, y = weight))
> e3$x
age
> e3$y
weight
在前面的例子中,调用对象的所有分量的模式是 "name"。对于调用对象里面的标识符确实是这样,但是一个调用对象的分量还可以是任意类型的常量,尽管在该调用随后被成功执行时第一个分量最好是一个函数—或者是其它调用对象以对应的子表达式。模式名的对象可以用as.name通过字符串创建,因此我们可以如下修改 e2 对象
> e2[[1]] <- as.name("+")
> e2
x + y
为说明子表达式是自身调用的简单分量,考虑下面的例子
> e1[[2]] <- e2
> e1
x + y + 2
所有输入的成组括号在解析后的表达式中是受保护的。它们以单参数函数调用的方式展示,因此4 - (2 - 2) 在前缀方式中变成 "-"(4, "(" ("-"(2, 2)))。在求值过程中,( 操作符仅仅返回它的参数。
这有点不幸,但是编写一个同时保护用户输入,以最简形式保存并且保证解析一个语法分析过的表达式时可以返回一样的表达式的解析器/语法分析器不是一件容易的事情。因为很难做到,所以 R 的解析器不可以很好的可逆,同样它的语法分析器也不行,如下面的例子所示
> deparse(quote(c(1, 2)))
[1] "c(1, 2)"
> deparse(1:2)
[1] "c(1, 2)"
> quote("-"(2, 2))
2 - 2
> quote(2 - 2)
2 - 2
但是语法分析过的表达式可以得到和原始表达式一样的求值结果(直到精度错误)。
...流控制结构的内部存储...注意和 Splus不兼容...
Hits:Loading...
