Это не предназначено для такого использования.Reflection - это то, что вы используете, если во время компиляции вы не знаете, с чем имеете дело во время выполнения.Некоторые примеры:
- вам нужно использовать тип, настроенный в некотором файле свойств (
Class.forName("someTypeString").newInstance()
) - вы написали утилиту, которая извлекает содержимое вашего объекта для целей отладки
- вам нужен доступ к коду, который на самом деле вам не виден (частные поля, к которым вы не можете легко получить доступ, но вам нужно)
- еще много ... но большинствовремя очень особых случаев использования
Теперь то, что вы показали, является ссылкой на функцию (object::cancel
).Чтобы использовать ссылку на функцию, компилятор должен знать тип object
, а для этого типа должна существовать cancel
-функция.Поскольку object
относится к типу Any
, а условие if
имеет значение только во время выполнения, компилятор не знает, что доступна функция cancel
, и поэтому компиляция не удалась.
Примечаниечто если вы не делаете ничего особенного, вам лучше проверить общий тип / интерфейс.Так, например, если ваши объекты реализуют интерфейс Cancellable
, вы можете просто изменить свой код на что-то вроде следующего:
fun canceller(object: Any): KFunction<Any>? {
var canceller: KFunction<Any>? = null
// check if object is of type Cancellable
if (object is Cancellable) {
// make reference of the Cancellable::cancel-function
canceller = object::cancel // smart-cast acting
// or you could also call it directly: object.cancel()
}
return canceller
}
или, возможно, вы можете просто сэкономить эту функцию и в итоге получить что-то вроде:
val someObj : Cancellable = ...
// somewhere later:
someObj.cancel()
Отражение довольно дорого, и если вы не совсем уверены, для чего оно полезно, вам не следует его использовать.
Если вы действительно знали, что делаете ...тогда ладно ... конечно, также возможно вызывать эту функцию через отражение, и если вы просите о существовании функции через отражение, вы также должны вызывать ее через отражение:
object::class.members.first {
// note: I am using just the first function... if there are several, you need to check which one to use (parameter/type)
it.name == "cancel"
}
.call(object)