我只是想知道是否有办法强制函数只接受某些数据类型,而不必在函数内检查它; 或者,这是不可能的,因为R的类型检查是在运行时完成的(而不是那些编程语言,例如Java,在编译期间进行类型检查)?
例如,在Java中,您必须指定数据类型:
class t2 {
public int addone (int n) {
return n+1;
}
}
Run Code Online (Sandbox Code Playgroud)
在R中,可能有类似的功能
addone <- function(n)
{
return(n+1)
}
Run Code Online (Sandbox Code Playgroud)
但是如果提供了一个向量,则(显然)将返回一个向量.如果你只想接受一个整数,那么这是在函数中有一个条件的唯一方法,就像
addone <- function(n)
{
if(is.vector(n) && length(n)==1)
{
return(n+1)
} else
{
return ("You must enter a single integer")
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢,
克里斯
And*_*rie 18
这完全可以使用S3类.你的例子在上下文或R中有点做作,因为我想不出为什么人们想要创建单个值的类的实际原因.尽管如此,这是可能的.作为一个额外的好处,我演示了如何使用函数addone将一个值添加到数字向量(平凡)和字符向量(所以A转到B等):
首先创建一个通用的S3方法addone,使用S3调度机制UseMethod:
addone <- function(x){
UseMethod("addone", x)
}
Run Code Online (Sandbox Code Playgroud)
接下来,创建一个人为的类single,定义为传递给它的任何东西的第一个元素:
as.single <- function(x){
ret <- unlist(x)[1]
class(ret) <- "single"
ret
}
Run Code Online (Sandbox Code Playgroud)
现在创建处理各种类的方法.除非定义了特定的类,否则将调用默认方法:
addone.default <- function(x) x + 1
addone.character <- function(x)rawToChar(as.raw(as.numeric(charToRaw(x))+1))
addone.single <- function(x)x + 1
Run Code Online (Sandbox Code Playgroud)
最后,使用一些示例数据对其进行测试:
addone(1:5)
[1] 2 3 4 5 6
addone(as.single(1:5))
[1] 2
attr(,"class")
[1] "single"
addone("abc")
[1] "bcd"
Run Code Online (Sandbox Code Playgroud)
一些其他信息:
Hadley的devtools wiki是所有事物的宝贵信息来源,包括S3对象系统.
S3方法不提供严格的输入.它很容易被滥用.对于更严格的面向对象,请查看S4类,基于引用的类或Prototype基于对象的编程的proto包.
您可以编写如下的包装器:
check.types = function(classes, func) {
n = as.name
params = formals(func)
param.names = lapply(names(params), n)
handler = function() { }
formals(handler) = params
checks = lapply(seq_along(param.names), function(I) {
as.call(list(n('assert.class'), param.names[[I]], classes[[I]]))
})
body(handler) = as.call(c(
list(n('{')),
checks,
list(as.call(list(n('<-'), n('.func'), func))),
list(as.call(c(list(n('.func')), lapply(param.names, as.name))))
))
handler
}
assert.class = function(x, cls) {
stopifnot(cls %in% class(x))
}
Run Code Online (Sandbox Code Playgroud)
并使用它
f = check.types(c('numeric', 'numeric'), function(x, y) {
x + y
})
> f(1, 2)
[1] 3
> f("1", "2")
Error: cls %in% class(x) is not TRUE
Run Code Online (Sandbox Code Playgroud)
由于 R 没有装饰器,这有点不方便。这有点像hacky,并且存在一些严重的问题:
你失去了惰性求值,因为你必须求值一个参数来确定它的类型。
在通话时间之前,您仍然无法检查类型;真正的静态类型检查允许您检查甚至从未实际发生的调用的类型。
由于 R 使用惰性求值,(2) 可能使类型检查不是很有用,因为调用可能实际上直到很晚才发生,或者永远不会发生。
(2) 的答案是添加静态类型信息。您可能可以通过转换表达式来做到这一点,但我认为您不想去那里。
我发现stopifnot()对这些情况也非常有用.
x <- function(n) {
stopifnot(is.vector(n) && length(n)==1)
print(n)
}
Run Code Online (Sandbox Code Playgroud)
它如此有用的原因是因为如果条件为假,它会向用户提供非常明确的错误消息.
| 归档时间: |
|
| 查看次数: |
4581 次 |
| 最近记录: |