我一直在努力让对手的有效性得到提升。我读过Hadley's advanced programming并得到他所说的瞄准你的脚(用枪):
R不会保护你自己:你可以很容易地用脚射击自己,但是如果你没有用枪瞄准你的脚并扣动扳机,你就不会有问题。
所以这适用于S3
。为了寻求更严格的实施,我调查了S4
。
setValidity
的手册页提出了以下内容:
setClass("track",
representation(x="numeric", y = "numeric"))
t1 <- new("track", x=1:10, y=sort(stats::rnorm(10)))
## A valid "track" object has the same number of x, y values
validTrackObject <- function(object) {
if(length(object@x) == length(object@y)) TRUE
else paste("Unequal x,y lengths: ", length(object@x), ", ",
length(object@y), sep="")
}
## assign the function as the validity method for the class
setValidity("track", validTrackObject)
## t1 should be a valid "track" object
validObject(t1)
## Now we do something bad
t2 <- t1
t2@x <- 1:20
## This should generate an error
## Not run: try(validObject(t2))
底线:如果我没有将validObject添加到初始化器或构造函数中,那么我无能为力。同样来自Martin Morgan and bioconductor's Seth Falcon的这篇文章很有意思,尽管我总是t2@x <- 1:1111
。
我想我能做些什么呢?虽然例如matrix
类让我想知道是否有选项。
a <- matrix(c(1:12),3,4)
cbind(a,"somechar")
# or similarily
a[1,1] <- "b"
显然,matrix
的所有元素必须属于同一类。这就是为什么一旦添加了一个字符,所有元素都被强制转换为公共分母,即character
类。
所以我的问题是:这怎么可能?以什么方式定义矩阵类,它可以通过任何方式保护“所有元素的某些类”的限制?有没有办法对自定义类实现这样的限制?
例如:类'customlist'的类必须是命名列表,并且名称仅限于两个字符长。
答案 0 :(得分:1)
AFAIK,没有办法阻止你(或你的用户)做任务愚蠢的事情,而不是可能覆盖<-
。由于这是原始的,而且对于R来说非常基础,如果沿着这条路走下去,就有可能打破其他事情。
如果使用引用类,则可以包含允许在进行分配之前进行检查的访问器。
trackFactory <- setRefClass(
"track",
fields = list(
x = "numeric",
y = "numeric"
),
methods = list(
initialize = function(x, y)
{
assertIsValid(x, y)
x <<- x
y <<- y
},
assertIsValid = function(x, y)
{
if(length(x) != length(y))
{
stop(
"Unequal x,y lengths: ",
toString(c(length(x), length(y)))
)
}
},
setX = function(x)
{
assertIsValid(x, .self$y)
x <<- x
},
setY = function(y)
{
assertIsValid(.self$x, y)
y <<- y
}
)
)
track1 <- trackFactory$new(1:10, runif(10))
track1$setX(1:5)
## Error in assertIsValid(x, .self$y) : Unequal x,y lengths: 5, 10
不幸的是,您仍然可以使用直接分配来跳过检查。
track1$x <- 1:7