Выражение 'classLevel' типа 'Any' не может быть вызвано как функция. Функция invoke () не найдена - PullRequest
0 голосов
/ 05 января 2019

Рассмотрим следующий класс:

class Test {
    val classLevel = object {
        operator fun invoke() = println("test class level property invocaton")
    }

    fun foo() {
        val functionLevel = object {
            operator fun invoke() = println("test invocation")
        }
        functionLevel() // no problem
        classLevel() // Expression 'classLevel' of type 'Any' cannot be invoked as a function. The function 'invoke()' is not found
    }
}

Почему второй вызывает свойство класса, а не компилируется? Он объявляется так же, как и в функции.

1 Ответ

0 голосов
/ 06 января 2019

Я думаю, что это о типах.

Поле classLevel имеет анонимный тип (подтип Any, созданный выражением объекта). Этот тип имеет метод invoke().

Однако этот тип не виден за пределами класса. Таким образом, если свойство имеет метод получения (то есть оно не является частным), метод получения не может возвращать анонимный тип; он должен возвращать ближайший именованный тип, который является Any. И Any не имеет invoke() метода.

Я не уверен, будет ли код в классе использовать метод получателя, если он доступен, или тип базового поля должен точно соответствовать типу получателя, если таковой имеется. Но в любом случае, очевидно, что если есть метод получения, ссылка на classLevel внутри класса дает вам ссылку Any, и поэтому вы не можете вызвать invoke() для нее. (И вы не можете уменьшить ссылку на ваш тип объекта, который имеет invoke(), потому что у этого типа нет имени.)

Одним из решений, как вы нашли, является сделать поле закрытым; это удаляет получатель и позволяет его базовому типу быть фактическим типом объекта, поэтому invoke() тогда доступен для вызова.

Другой вариант - определить именованный тип для реализуемого объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...