不太确定如何在不深入了解我的特定编程问题的情况下提出这个问题。所以,这个问题有点相关,但要简单得多。我试图了解 R 在分配给 S4 类的插槽时适用的程序。我有自定义访问和分配功能,“$”和“$<-”。
我注意到两点:
以下是用于说明的玩具示例。非常感谢对第 1 点的评论和对第 2 点的回答。
setClass("Person"
, representation(FirstName = "character"
, LastName = "character"
, Birthday = "Date")
)
setMethod("$", signature(x = "Person"), function(x, name) {
print("Just called $ accessor")
slot(x, name)
})
setMethod("$<-", signature(x = "Person"), function(x, name, value) {
print("Just called $ assignment")
slot(x, name) = value
x
})
objPeople = new("Person"
, FirstName=c("Ambrose", "Victor", "Jules")
, LastName=c("Bierce", "Hugo", "Verne")
, Birthday=seq(as.Date("2001/01/01"), as.Date("2003/12/31"), by="1 year"))
# This assignment will work. When assigning, there will be a call to the "$" accessor function. Why?
objPeople$FirstName[2] = "Joe"
# This assignment will not make a call to the "$" accessor function. Why?
objPeople$FirstName = "Ambroze"
Run Code Online (Sandbox Code Playgroud)
请记住,这[只是另一个函数,就像[<-. 所以为了做到
objPeople$FirstName[2] = "Joe"
Run Code Online (Sandbox Code Playgroud)
在$将运行第一和回报的东西,在[<-可以操作的。就像是
'$<-'(objPeople, "FirstName", '[<-'( '$'(objPeople, "FirstName"), 2, "Joe"))
Run Code Online (Sandbox Code Playgroud)
因此,为了进行子集化,它必须提取名字。但是随着
objPeople$FirstName = "Ambroze"
Run Code Online (Sandbox Code Playgroud)
那只是一个
'$<-'( objPeople, "FirstName", "Ambroze")
Run Code Online (Sandbox Code Playgroud)
所以你不需要调用访问器。您只是直接调用赋值函数。
如果你想在你的班级上有一个自定义的子集,它会在Person[]级别上。如果您想在 FirstName 插槽上使用自定义子集,则必须使 FirstName 插槽成为它自己的类,您可以在其中重新定义该[方法。