我在理解以下代码的差异方面遇到了麻烦:
第一篇:
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中进行了测试
答案 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)<-
表单。