【问题标题】:Lists of reference class objects are not changing when the objects they were initialized with are changed当它们被初始化的对象改变时,引用类对象的列表不会改变
【发布时间】:2015-11-16 10:55:55
【问题描述】:

我有一个引用类对象列表,我希望当我更改初始化列表的对象之一时,列表中的相应条目也应该更改。情况并非如此,如以下示例代码所示,如​​果我列出squaretriangle,然后将square 更改为octagon。该列表仍将分别具有 4 边和 3 边的多边形。反过来也是如此。如果我更改列表的元素,初始变量保持不变。有谁知道这是为什么,或者是否有解决方法?谢谢!

Polygon <- setRefClass("Polygon", fields = c("sides"))
square <- Polygon$new(sides = 4)
triangle <- Polygon$new(sides = 3)
octagon <- Polygon$new(sides = 8)

pList <-list(square,triangle)

print(pList)
# [[1]] Reference class object of class "Polygon"
# Field "sides": [1] 4
# [[2]]    # Reference class object of class "Polygon"
# Field "sides":  [1] 3

square<-octagon
# Reference class object of class "Polygon"
# Field "sides":  [1] 8

square #the variable square changes
# Reference class object of class "Polygon"
# Field "sides": [1] 8

pList # but the entry in pList does now.
# [[1]] Reference class object of class "Polygon"
# Field "sides": [1] 4
# [[2]] Reference class object of class "Polygon"
# Field "sides":  [1] 3

#the same is true the other way around, changing the item corresponding to triangle in the list, 
#does not change the object triangle
triangle$sides #3
pList[[2]]$sides #3
pList[2]<-octagon
pList[[2]]$sides #8
triangle$sides #3

有谁知道这是为什么,或者是否有解决办法?

如果我更改对象的各个字段,更改确实会传播,如下面的代码所示,但我正在使用的实际类比此处使用的简单多边形类复杂得多,因此更改每个对象内的所有字段对我来说并不是真正的解决方案。

square <- Polygon$new(sides = 4)
triangle <- Polygon$new(sides = 3)
octagon <- Polygon$new(sides = 8)
pList <-list(square,triangle)

#changing the list element changes the variable triangle
triangle$sides #3
pList[[2]]$sides#3
pList[[2]]$sides<-12
pList[[2]]$sides #12
triangle$sides #12

square <- Polygon$new(sides = 4)
triangle <- Polygon$new(sides = 3)
octagon <- Polygon$new(sides = 8)
pList <-list(square,triangle)

#changing the variable triangle changes the list element
triangle$sides #3
pList[[2]]$sides#3
triangle$sides<-12
pList[[2]]$sides #12
triangle$sides #12

【问题讨论】:

    标签: r reference-class


    【解决方案1】:

    列表条目是值而不是引用/指针。 ReferenceClass 对象引用(或指向)与它们关联的数据(即字段)。

    如果您想在列表中编辑“类指针”而不直接接触列表对象,则新的“PolygonPointer”类可能是您的解决方法:

    PolygonPointer <- setRefClass("PolygonPointer", fields = list(target = "Polygon"))
    
    pointer1 <- PolygonPointer(target = square)
    pointer2 <- PolygonPointer(target = triangle)
    
    lst <- list(pointer1, pointer2)
    
    pointer1$target <- octagon
    

    输出是:

    > lst
    [[1]]
    Reference class object of class "PolygonPointer"
    Field "target":
    Reference class object of class "Polygon"
    Field "sides":
    [1] 8
    
    [[2]]
    Reference class object of class "PolygonPointer"
    Field "target":
    Reference class object of class "Polygon"
    Field "sides":
    [1] 3
    

    但请注意,这样的构造是危险的——例如,默认的复制构造函数会执行“深度复制”,同时也会复制指向的对象。例如:

    pointer3 <- pointer1$copy()
    pointer3 <- triangle
    pointer1 # still points to the octagon
    

    如果您只想复制指针本身而不是其引用的对象,则必须覆盖 PolygonPointer 的复制构造函数。

    【讨论】:

      猜你喜欢
      • 2013-12-09
      • 2013-06-27
      • 1970-01-01
      • 2015-01-30
      • 2012-09-12
      • 2017-10-21
      • 1970-01-01
      • 2013-05-15
      • 1970-01-01
      相关资源
      最近更新 更多