R6类中Active Binding是否需要返回self?
关于R6 Active Binding返回self的必要性解答
问题背景
在Hadley所著《Advanced R(第二版)》的R6章节中,Person类的name active binding在设置值时,会返回self(且为非隐形返回)。此前书中提到,方法中隐形返回self是为了支持链式调用,但不确定active binding是否支持链式调用,因此疑问此处返回self是否有必要。
对应的Person类定义代码:
Person <- R6Class("Person", private = list( .age = NA, .name = NULL ), active = list( age = function(value) { if (missing(value)) { private$.age } else { stop("`$age` is read only", call. = FALSE) } }, name = function(value) { if (missing(value)) { private$.name } else { stopifnot(is.character(value), length(value) == 1) private$.name <- value self } } ), public = list( initialize = function(name, age = NA) { private$.name <- name private$.age <- age } ) )
解答
返回self是有实际意义的,因为R6的active binding支持链式调用,具体原因如下:
- 赋值表达式的默认返回值是所赋的内容,比如
p$name <- "Alice"默认会返回字符串"Alice"。但如果active binding的setter返回self,就能改变这个返回结果,让赋值操作的结果变成对象本身。 - 这样我们就可以写出链式操作的代码,比如:
p <- Person$new("Bob") # 通过链式调用,设置name后直接获取age (p$name <- "Alice")$age
如果setter不返回self,上面的代码会报错,因为"Alice"字符串没有age属性;而返回self后,括号内的结果是R6对象,就能直接访问age字段。
- 虽然书中提到方法用隐形返回
self,但active binding的setter用非隐形返回也不会有问题:单纯赋值时用户不会关注返回值,而需要链式操作时,这个返回的self就能派上用场。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

