`class< -`()的意外行为

时间:2016-11-03 13:36:25

标签: r

我在理解以下代码的差异方面遇到了麻烦:

第一篇:

a <- 123
class(a) <- 'FOO'

b <- a
class(b) <- 'BAR'

class(a) # returns 'FOO'
class(b) # returns 'BAR'

第二篇:

a <- 123
`class<-`(a,'FOO')

b <- a 
`class<-`(b,'BAR')

class(a) # returns 'BAR' ! so class attribute has been replaced  also on "a"
class(b) # returns 'BAR'

据我所知,b <- a应该创建a的副本,而不是立即创建,但只要b被修改。 但是看第二种情况,似乎使用`class<-(x,"")函数(我希望它只是class(x)<-""非语法糖),副本不会被创建,改为修改原始对象。

我错过了什么(可能在文档中)?

在R版本3.2.5中进行了测试

1 个答案:

答案 0 :(得分:4)

这是旧版本R中出现的R错误。最新版本的R-devel已经按预期工作 - 该对象未进行适当修改。它在R-devel版本70636中修复。

请注意,示例不太正确。由于R的值语义,不允许函数就地修改它们的参数(环境除外)。因此,class<-等函数必须修改其参数的副本,并返回此副本,因此该示例应使用a <- 'class<-'(a,'FOO')而不是'class<-'(a, 'FOO')

当在R中实现替换函数(如'class&lt; - ')时,无法违反值语义。但是,在a <- 'class<-'(a, 'FOO')这样的作业中,我们发现没有属性集的旧版“a”将不再使用。为了提高效率,许多替换函数在C中实现,它们通过原位修改它们的参数来违反R的值语义,但是当知道任何函数不使用该参数的值时其他变量。顺便提一下,这个优化已经(重新)添加到相应版本的R中的class<-

我认为函数'class<-'(和类似的)不应该由R程序直接调用。在这个简单的情况下,它应该像问题中描述的那样简单,但通常映射替换调用对'class<-'等函数的调用更复杂。此外,AST解释器和字节码解释器之间的实现目前不同。目前可以在R language definition (for the AST interpreter)compiler documentation中找到更多信息,但这些是R程序不应该依赖的实现细节。 R程序应始终使用class(x)<-表单。