因为 ggproto 类对象是环境而不是类似列表的结构,可以使用is.environment(GeomFunction)
. 环境不遵循例如向量所遵循的修改时复制启发式。
为修改目的制作副本的正确方法是使用ggproto
构造函数。从技术上讲,您正在制作GeomFunction
.
library(ggplot2)
GeomFunction2 <- ggproto(NULL, GeomFunction)
GeomFunction2$required_aes <- c("x", "y", "fun")
identical(GeomFunction$required_aes, GeomFunction2$required_aes)
#> [1] FALSE
由reprex 包(v2.0.1)创建于 2022-01-09
另外,由于 ggproto 对象是环境,我们可以使用它ls()
来查看它们包含的内容。
ls(GeomFunction2)
#> [1] "required_aes" "super"
ls(GeomFunction)
#> [1] "draw_panel" "super"
ls(Geom)
#> [1] "aesthetics" "default_aes" "draw_group" "draw_key"
#> [5] "draw_layer" "draw_panel" "extra_params" "handle_na"
#> [9] "non_missing_aes" "optional_aes" "parameters" "required_aes"
#> [13] "setup_data" "setup_params" "use_defaults"
可以看到层次结构中的每一层都只包含相对于父级的变化,以及一个神秘的super
对象,它是一个函数。调用该super
函数时,您可以看到它检索父类。
class(GeomFunction2$super())
#> [1] "GeomFunction" "GeomPath" "Geom" "ggproto" "gg"
由reprex 包(v2.0.1)创建于 2022-01-09
没有super
对象Geom
表明这Geom
是根类。
该类存在的原因ggproto
是允许扩展重用大量代码,而不必从头开始构建它们。理论上,ggproto 类似于 R6 或引用类的面向对象编程,但我认为 R6/引用类有一些缺点,不允许跨包继承它们的类。