我正在编写我的第一个R包,我试图找出给S4对象中的一个插槽分配值的最佳方法,同时要记住,终端用户不应该对正在使用的S4类结构的细节感到烦恼。以下哪一项是最好的?
object@MySlot <- value**:**直接访问插槽的
我理解这种糟糕的做法(例如,这个问答)。slot(object, "MySlot") <- value**:**的
R help表示,在获取值时不进行检查,但在设置时进行检查(假设check没有设置为FALSE)。这在我看来是合理的,而且我觉得这是一种很好的方法,因为我不需要编写自己的get/set方法,如下所示。setReplaceMethod()**:**
这种方法与上面的第二种选择相比有什么不同?生成必要的get/set方法需要做更多的工作,但我可以更明确地确保写入槽的值对于该槽类型是有效的。
setGeneric("MySlot",function(object ){ standardGeneric("MySlot") }) setMethod("MySlot",signature="MyClass",definition = function(object @MySlot) }) setGeneric("MySlot<-",函数(对象,值){ standardGeneric("MySlot<-") }) setReplaceMethod(MySlot,signature= "MyClass",函数(Object)){ object@MySlot<- value validObject(object) #可以添加其他检查返回(对象) })发布于 2014-03-21 02:16:44
根据定义,“不必对S4类结构的细节大惊小怪”意味着最终用户不应该知道您的插槽。因此,您在步骤2和步骤3中编写的任何包装器都更适合内部一致性检查。我认为更重要的是检查那些您认为您的完整性检查将使用单元测试失败的边缘情况。
正如您已经指出的,#1可以很容易地被排除,并且应该只在内部方法中使用。您是鼓励#2还是实现#3取决于变量的内容和个人品味,但我会鼓励后者。例如,如果您有一个logical标志,您可以使用#2,但更具有描述性的是enableFoo()。尽管如此,如果您必须考虑开发人员的时间(在现实生活中几乎总是正确的),那么您应该简要地考虑一下,对于可能不会经常被访问的成员(例如,只有不到1%的用户),将变异器降级到slot<-之间的权衡,而不是像第3中那样为所有东西实现自定义的变异器。
最后,由于几乎所有三个R的面向对象编程系统本质上都是语法糖,并且在语义上没有真正被该语言所尊重(只有S4才能声称有一些例外),所以很容易忘记以其他语言实现的面向对象编程的基本思想:在方法之外执行的任何代码都不应该知道对象的成员。您正在为这个世界提供一个外部接口,它是并且应该是一个黑匣子。
https://stackoverflow.com/questions/22546638
复制相似问题