typeof
возвращает тип внутреннего представления C и не используется для отправки метода.Строго говоря, вы не можете думать о типах как о «суперклассах».
Вместо этого базовые классы (числовой, символьный, список, функция и т. Д.), Которые примерно соответствуют именам, возвращаемым typeof
, но не всегда (например, тип double имеет числовой класс, special и замыкание имеют функцию класса, а класс data.frame имеет список типов!).
С системами S3 и S4 вы можете создаватьнетривиальные классы, использующие базовые классы (но необязательно расширение одного из них! пример: setClass("foo", list(a="numeric",b="character")
не расширяет ни один из базовых классов ).
Для объектов из этих базовых классов is.object
возвращает FALSE
.Как сказано в документации, эта функция обеспечивает очень быстрый способ проверить, принадлежит ли объект пользовательскому классу S3 или S4 (т.е. не относится к базовым классам).
После приведения x
в качестве «фальшивого» вашегоОбъект формально не относится к «числовому» классу:
is(x, "numeric")
#FALSE
, но его можно интерпретировать как базовый «числовой» объект:
is.numeric(x)
#TRUE
И именно поэтому +
работает здесь.Итак, внутренне, как уже сказал @Richie, метод по умолчанию интерпретирует x
как числовой базовый класс.
Этот концептуальный беспорядок из-за неформальной обработки классов S3.Вместо этого используйте S4.
соответствие между typeof (.) И базовым классом (.):
typeof(.) class(.)
NULL "NULL" "NULL"
1 "double" "numeric"
1:1 "integer" "integer"
1i "complex" "complex"
list(1) "list" "list"
data.frame(x=1) "list" "data.frame"
pairlist(pi) "pairlist" "pairlist"
c "special" "function"
lm "closure" "function"
formals(lm)[[1]] "symbol" "name"
formals(lm)[[2]] "symbol" "name"
y~x "language" "formula"
expression((1))[[1]] "language" "("
(y~x)[[1]] "symbol" "name"
expression(x <- pi)[[1]][[1]] "symbol" "name"