You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让R6类用户提供可访问self的自定义calc函数?

解决方案

调整自定义calc函数的环境方向是正确的,这能让用户的代码自然访问R6实例的self对象。要避免依赖内部属性.__enclos_env__,可以通过environment(self)获取实例的封闭环境,这是更规范的公开访问方式。

优化后的R6类实现

library(R6)

B <- R6Class("B",
             public = list(
               initialize = function(calc) {
                 # 获取实例的封闭环境,替代内部的.__enclos_env__
                 inst_env <- environment(self)
                 private$calc <- calc
                 # 将自定义calc的环境设置为实例的封闭环境
                 environment(private$calc) <- inst_env
               },
               run = function(x) {
                 private$calc(x)
               },
               result_codes = list(OK = 1, NOK = 2)
             ),
             private = list(
               calc = NULL
             )
)

测试代码

# 用户自定义calc函数,直接使用self
b <- B$new(function(x) {
  if (x >= 0) {
    self$result_codes$OK
  } else {
    self$result_codes$NOK
  }
})

b$run(1)  # 返回1
b$run(-1) # 返回2

原理说明

  • environment(self)会返回R6实例的封闭环境,这个环境包含了self和private对象的作用域,是公开且稳定的访问方式,不会依赖内部未文档化的属性。
  • 将自定义calc函数的环境设置为实例的封闭环境后,函数内部就能直接识别self,和类中定义的方法拥有一致的作用域。

备选方案(显式传递self)

如果不想调整函数环境,也可以在调用calc时显式传递self作为参数,但需要用户修改自定义函数的参数列表:

B <- R6Class("B",
             public = list(
               initialize = function(calc) {
                 private$calc <- calc
               },
               run = function(x) {
                 # 调用时传递self
                 private$calc(self, x)
               },
               result_codes = list(OK = 1, NOK = 2)
             ),
             private = list(
               calc = NULL
             )
)

# 用户需要接收self参数
b <- B$new(function(self, x) {
  if (x >= 0) {
    self$result_codes$OK
  } else {
    self$result_codes$NOK
  }
})

b$run(-1) # 返回2

这种方式无需修改环境,但用户需要额外处理self参数,不如调整环境的方式直观。

内容的提问来源于stack exchange,提问作者thothal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 13:54:59