R6中使用print函数时主动绑定为何重复输出内容?
为什么R6主动绑定中使用
print()会导致重复输出? 这事儿的根源其实和R6主动绑定的工作机制,以及R控制台的自动打印行为有关,咱们一步步拆解清楚:
首先要明确:R6里的主动绑定(active binding)本质是一个函数——当你访问a$MailPriv这类主动绑定属性时,其实是在调用对应的绑定函数,而不是直接读取一个静态变量值。
咱们看你第一个例子里的主动绑定定义:
MailPriv = function(){ print(private$privMail) }
当你执行a$MailPriv时,会连续发生两件事:
- 函数内部执行
print(private$privMail),这会直接在控制台输出一次"colin@thinkr.fr"; - 别忘了
print()函数的返回值就是它打印的那个对象本身(你可以在控制台单独测试:x <- print("test"),然后查看x的值,会发现就是"test")。所以这个主动绑定函数执行完毕后,会把print()的返回值(也就是目标邮箱字符串)作为自己的返回值。而R控制台有个默认行为:如果一个表达式的结果没有被赋值给变量,就会自动打印这个结果。于是这就触发了第二次相同内容的输出。
对比你去掉print()的情况:
MailPriv = function(){ private$privMail }
这时候函数的返回值就是邮箱字符串,控制台自动打印这个返回值,所以只会输出一次,完全符合预期。
如果想验证这个逻辑,你可以试试在主动绑定函数里让它返回NULL:
team3 <- R6::R6Class("Team", public = list(mail = "colin@thinkr.fr"), private = list(privMail = "colin@thinkr.fr"), active = list( MailPriv = function(){ print(private$privMail) return(NULL) } ) ) a3 <- team3$new() a3$MailPriv #> [1] "colin@thinkr.fr"
这时候只会输出一次,因为函数返回NULL,控制台虽然会处理这个返回值,但默认不会显示NULL的输出,也就不会再重复打印邮箱字符串了。
总结来说:两次输出是因为print()的执行直接输出一次内容,加上R控制台自动打印函数的返回值(而print()的返回值恰好就是被打印的内容),最终导致了重复输出的现象。
内容的提问来源于stack exchange,提问作者Colin FAY
相关产品推荐
相关产品推荐

