R语言与面向对象的编程(1):proto对象


专注系列化、高质量的R语言教程


本系列将介绍R语言中三个与面向对象的编程(Object-Oriented Programming,OOP)相关的工具包:protoR6和基础包methods。这是一个承上启下的系列,上承《自定义ggplot2绘图系统函数》系列,下启《基于mlr3工具包的机器学习》系列(该系列将在本系列之后推出)。这两个系列的编程风格都属于OOP,前者基于proto包的proto对象,后者基于R6包的R6类。

本篇推文介绍的是proto对象,在推文定义一个简单的统计变换函数中已有了初步介绍。本篇将介绍如下内容:

  • 创建proto对象

  • proto对象和普通对象的区别

  • proto对象备份

  • proto对象委托

1 创建proto对象

OOP风格又分为两种风格:一种是基于对象的编程(Object-Based Programming),也称原型编程(Prototype Programming);另一种是基于类的编程(Class-Based Programming)。proto工具包采用的是前者。

因为没有“类”的概念,原型编程可以更自由地定义对象。从形式上看,定义proto对象与定义列表(list)很相似,使用的是proto()函数:

library(proto)
oo <- proto(
  
  x = 1,
  
  add = function(.) {.$x = .$x + 1}
)

如上代码就定义了一个proto对象oo。proto对象的元素分为两类:一类称为属性(field),在R中就是变量(variable),如oo中的x;另一类称为方法(method),在R中就是函数(function),如ooadd

proto对象中的元素也可以使用符号$进行引用:

oo$x
## [1] 1

oo$add()

因为add()函数没有返回值,因此语句oo$add()输出内容为空。

在proto对象内部的函数中,使用点号.表示对象本身。因此.$x = .$x + 1意味着add()函数每运行一次,就会使元素x在原有的基础上加1:

oo$x
## [1] 2

oo$add()
oo$x
## [1] 3

这种对象是显著不同于数据框、列表等普通对象的。对于面向过程的编程而言,没有赋值符号的代码只起到输出对象内容的作用,而不会改变自身或其他对象的内容。

当然,proto对象中的函数不一定要改变其元素的值,也可以输出结果(函数有输出结果的方法见推文如何自定义R语言函数):

## 定义
oo2 <- proto(
  
  x = 1:5,
  
  add = function(.) sum(.$x)
)

## 运行
sum(oo2$x)
## [1] 15
oo2$add()
## [1] 15

2 与普通对象的区别

对于普通对象来说,有如下代码:

a <- 2
b <- a

b
## [1] 2

通过上述代码,我们将对象a的当前值传递给对象b。但是,ab是完全两个独立的对象,a后来的变化不会影响到b

a <- 3
b
## [1] 2

通过上述代码,我们修改了a的值,而b的值不会随之变化。

对于proto对象则不同。我们先将oo2对象“复制”给oo3,此时oo2$xoo3$x显然是相同的:

oo3 <- oo2

oo2$x
## [1] 1 2 3 4 5
oo3$x
## [1] 1 2 3 4 5

之后,我们再修改oo2$x的值,可以发现oo3$x也会随之改变:

oo2$x <- oo2$x + 1

oo2$x
## [1] 2 3 4 5 6
oo3$x
## [1] 2 3 4 5 6

对于proto对象而言,赋值符号<-起到的不是“备份”的作用,而是“重命名”的作用。在本例中,也就是说oo2oo3只是同一对象的两个名称而已。通过下面代码可以看出,二者指向的是同一对象,因此改变其中一个,另一个也会随之变化:

oo2
## <environment: 0x000002133f8b4ae8>
## attr(,"class")
## [1] "proto"       "environment"

oo3
## <environment: 0x000002133f8b4ae8>
## attr(,"class")
## [1] "proto"       "environment"

3 proto对象备份

因为proto对象可以进行自我更新,因此有必要提前对其进行备份。但是上节的方法起不到“备份”效果,那该如何进行备份呢?方法是比较固定的,例如:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>