4

我从git 上的一个开源存储库中获得了这个。这显示了 S3 类的泛型和方法的编写。但我不理解分配函数的符号或约定。以下是我的问题:

  • 使用反引号``来定义函数名。通常我们不会使用反引号甚至双引号来分配变量/函数,但我看到这种情况发生了很多次。这是命名约定吗?
  • 为什么.包含在 blob 名称之前?通常它不会被称为 blob 而一个方法是 method.blob 吗?
  • 为什么那里有[括号?特别是,[<-[[<-。我们是否在执行某种双重分配?

希望有人能够阐明什么是哈

#' @export
 `[.blob`  <- function(x, i, ...) {
  new_blob(NextMethod())
}

#' @export
`[<-.blob` <- function(x, i, ..., value) {
  if (!is_raw_list(value)) {
    stop("RHS must be list of raw vectors", call. = FALSE)
  }

  NextMethod()
}

#' @export
 `[[<-.blob` <- function(x, i, ..., value) {
  if (!is.raw(value) && !is.null(value)) {
    stop("RHS must be raw vector or NULL", call. = FALSE)
  }

  if (is.null(value)) {
    x[i] <- list(NULL)
    x
  } else {
    NextMethod()
  }
}
4

1 回答 1

7

概括

如果您要在 R 中创建一个需要“不同”子集和赋值行为的新对象,则应该为这些操作创建关联的方法。

  • .IS 以您期望的方式工作 - 方法调度

  • [.blob正在覆盖 S3[子集运算符

  • [<-.blob覆盖 S3[<-运算符(即向量子集赋值)

  • [[<-.blob覆盖 S3[[<-运算符(即列表子集分配)

  • 默认情况下,特殊符号(例如,反引号、方括号、百分号、名称中带有空格的变量)不能“分配给”。为此,如果您将其用反引号括起来,它就可以工作。例如,一个名为的变量A B不能用 分配A B <- 1,而`A B` <- 1有效(信用@r2evans)

例子

子集

举个例子,这允许您为您的对象[.blob创建自己的子集操作。blob

## Create your own blob object (class)
blob <- 1:5
attr(blob, "class") <- "blob"

## create a subset operator, which in this example just calls the next method in the s3 dispatch chain 
`[.blob` <- function(x, i, j, ...) NextMethod()

由于我们没有在我们自己的子集方法中做任何特别的事情,这就像正常的 R 向量一样工作

blob[3]
# [1] 3

但是,我们可以让子集操作做任何我们想做的事情,例如总是返回向量的第一个元素

## define the function to always subset the first element
`[.blob` <- function(x, i, j, ...) { i = 1; NextMethod() }

现在你的blob对象只会返回第一个元素。

blob[1]
# [1] 1
blob[2]
# [1] 1
blob[3]
# [1] 1

任务

[<-同样对于其中一个赋值运算符,如果您重载

`[<-.blob` <- function(x, i, j, ...) { i = 5; NextMethod() }

这将始终为 blob 对象的第 5 个元素分配新值

blob[1] <- 100
blob
# [1]   1   2   3   4 100
# attr(,"class")
# [1] "blob"

后记号

使用了反引号,因此我们可以将函数/变量分配给特殊符号。

例如,尝试为[符号分配一个向量

[ <- 1:5
# Error: unexpected '[' in "["

而用刻度包围它可以让它通过(尽管不推荐这个例子)

`[` <- 1:5
`[`
# [1] 1 2 3 4 5
于 2018-04-10T02:55:32.817 回答