R的命名空间机制允许一个export
函数,然后用户可以看到它们。此外,它允许来自其他包的import
函数。虽然出口的好处是显而易见的,但我在理解进口的好处方面存在更多问题。
似乎有一个好处,即可以使用其他软件包中的函数而无需附加软件包,从而节省内存。这在1.6.4 in the writing R extensions manual部分中举例说明。
但是,导入功能必须具有其他好处。特别是,section 1.6.6 (that deals with S4 classes)显示了stats4包的namespace
:
export(mle)
importFrom("graphics", plot)
importFrom("stats", optim, qchisq)
## For these, we define methods or (AIC, BIC, nobs) an implicit generic:
importFrom("stats", AIC, BIC, coef, confint, logLik, nobs, profile,
update, vcov)
exportClasses(mle, profile.mle, summary.mle)
## All methods for imported generics:
exportMethods(coef, confint, logLik, plot, profile, summary, show, update, vcov)
## implicit generics which do not have any methods here
export(AIC, BIC, nobs)
这里导入的函数既不是S4类也不是泛型(使用导入也是有意义的,如that section中的示例所述),但函数如plot
来自R启动时自动加载的graphics
包。
因此,我的问题是,导入plot
,optim
或qchisq
等功能有什么好处?
答案 0 :(得分:23)
如果从包Bar导入函数foo
,则无论用户对其搜索路径做什么,都会找到它,例如,通过附加也具有函数foo
的包Baz。如果没有名称空间,包代码会突然发现自己使用Baz::foo
。还有效率问题(foo
是立即找到的,而不是在搜索搜索路径上的所有符号之后),但对于大多数应用程序来说,这些问题可能很简单。同样,importFrom
是对import
的改进,因为更少的冲突(或使用非预期的功能)和更有效的查找。
使用S4(和S3),事情会变得非常复杂。像graphics::plot
这样的非泛型函数可以在两个不同的包中提升为泛型(带setGeneric
),每个泛型都可以附加自己的一组方法。包作者需要准确了解哪个plot
泛型,以及哪些方法调度表,它们的类和方法都可以看到。
调用pkg::foo
的函数始终会解析为预期的函数。它要求pkg列在DESCRIPTION文件的Depends:字段中(可能在Imports中:但是它似乎误导了广告而不是从pkg导入),污染了用户的搜索路径。它还涉及两个符号查找和一个函数调用(::
),因此效率较低。对我来说,懒惰和缺乏关注细节部分也会使用::
作为单调乏味且容易出错。
包codetoolsBioC(通过带有用户名和密码readonly
的svn)可以从现有包中生成NAMESPACE文件(或者至少可以在最近对R-devel进行更改之前在包上引入NAMESPACE没有一个;我没有在这样的包上尝试过codetoolsBioC。)