【问题标题】:Alternative to writing to global variable from within function从函数内部写入全局变量的替代方法
【发布时间】:2022-10-14 22:03:11
【问题描述】:

我有一些有效的代码,但我理解这依赖于不良做法。要使用问题的简单表示,请使用代码;

operation <- function(index){
  a <- 0
  if(data[index] == FALSE){
    data[index] <<- TRUE
    a <- a + 1}
  
  a <- a + 1
  return(a)
}

data <- c(FALSE, FALSE, FALSE)

x <- 0
x <- x + operation(sample(c(1,2,3),1))
x <- x + operation(sample(c(1,2,3),1))
x <- x + operation(sample(c(1,2,3),1))
x

“操作”函数有两个目的 - 首先,如果输入指定的值为 FALSE,则输出 2,如果 TRUE,则输出 1,重要的是,将输入更改为 TRUE,以便将来调用相同输入返回 1。

这样做的问题是操作函数引用了一个我知道我的用例将始终存在的全局变量,但假设可能不存在,并且该函数使用&lt;&lt;- 命令写入全局变量,我理解这是难以置信的不好的做法。

有没有更好的实践方法来实现相同的功能而无需将函数写入全局变量?

【问题讨论】:

    标签: r


    【解决方案1】:

    根据设计,R 确实只返回一个对象。要返回多个对象,您必须将它们存储在列表中并将两个元素都用作输入。

    operation <- function(index, data){
      a <- 0
      if(data[index] == FALSE) {
        data[index] <- TRUE
        a <- a + 1}
      
      a <- a + 1
      return(list(a = a, data = data))
    }
    
    data <- c(FALSE, FALSE, FALSE)
    x <- 0
    
    set.seed(999)
    res <-  operation(sample(1:3, 1), data)
    x <- x + res$a
    res <-  operation(sample(1:3, 1), res$data)
    x <- x + res$a
    res <-  operation(sample(1:3, 1), res$data)
    x <- x + res$a
    
    x
    #> [1] 5
    res$data
    #> [1]  TRUE FALSE  TRUE
    

    另一种选择是创建一个具有两个绑定 xdata 的 R6-Object 并更改

    【讨论】:

      【解决方案2】:

      我们可以使用面向对象的编程。我们在这里使用 proto 包,但也可以使用某些其他面向对象的编程系统。 p 是一个 proto 对象,它包含 data 和一个方法 op

      library(proto)
      
      p <- proto(op = function(., index) {
        a <- 0
        if( ! .$data[index] ) {
          .$data[index] <- TRUE
          a <- a + 1
        }
        a <- a + 1
        return(a)
      })
      
      p$data <- c(FALSE, FALSE, FALSE)
      
      x <- 0
      x <- x + p$op(sample(c(1,2,3),1))
      x <- x + p$op(sample(c(1,2,3),1))
      x
      

      【讨论】:

        猜你喜欢
        • 2022-08-02
        • 2013-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多