Вызов метода с универсальным типом в Kotlin с несколькими ограничениями типов параметров - PullRequest
2 голосов
/ 02 апреля 2019

У меня есть следующее определение метода интерфейса, написанное на Java:

<T extends View & ISpecificView> T getSpecificView();

Код потребителя на основе Java может работать с этим методом, просто вызывая его и обрабатывая возвращаемое значение как объект, расширяющийКласс View и реализация интерфейса ISpecificView следующим образом:

getContainer().getSpecificView().whateverTclassMethod()

Попытка вызвать тот же код в Kotlin Я получаю ошибку Type inference failed: Not enough information to infer parameter T (...) Please specify it explicitly в методе getSpecificView().Я хотел бы предоставить тип явно, но я не могу передать какой-либо конкретный класс, так как это может быть любой предок класса View, который реализует интерфейс ISpecificView.Передача одиночного View или ISpecificView не помогает - это приводит к Type argument is not within its bounds. Expected: View! Found ICustomView и наоборот.

Есть ли возможность передать эквивалент T extends View & ISpecificView Java в Kotlin при вызове методатак что я могу этим воспользоваться?

Ответы [ 2 ]

3 голосов
/ 02 апреля 2019

Подводя итог (и я надеюсь, что я правильно понял вопрос!), На Java вы можете сделать

final View view = getContainer().getSpecificView();  // or
final ISpecificView iview = getContainer().getSpecificView();

В Котлине тоже самое

val view: View = getContainer().getSpecificView()

Результаты в Type inference failed: Not enough information to infer parameter T


После 50 минут попыток и попыток ...
Просто создайте манекен class (аннотация?)

abstract class KView : View(), ISpecificView

И использовать его для явного задания универсального типа возвращаемого значения

val view: View = getContainer().getSpecificView<KView>()
view.whateverClassMethod()

val iview: ISpecificView = getContainer().getSpecificView<KView>()
iview.whateverInterfaceMethod()

// or just

(getContainer().getSpecificView<KView>() as View).whateverClassMethod()
(getContainer().getSpecificView<KView>() as ISpecificView).whateverInterfaceMethod()

Требуется конкретное приведение к View или ISpecificView, потому что если вы просто сделаете

getContainer().getSpecificView<KView>()

вы получите

class your.package$ExtendingClass cannot be cast to class your.package.KView

но это прекрасно.
Даже в Java вам нужно решить, хотите ли вы View или ISpecificView.


Таким образом, вы сможете работать со всеми методами View или ISpecificView.


Действительно, я не знаю, что еще попробовать. Надеюсь, кто-нибудь придумает что-нибудь получше.

Редактировать: если вы имеете в виду на Java, вы делаете

final ExtendedView ev = getContainer().getSpecificView();

ну, это немного неправильно imho, даже если он компилируется, так как вы не можете гарантировать, что тип возвращаемого значения действительно ExtendedView. Вы точно знаете, что он расширяет View и реализует ISpecificView.

0 голосов
/ 02 апреля 2019

Вы должны быть в состоянии достичь этого, используя следующее:

fun <T> getSpecificView() where T : View, T : ISSpecificView {}

Документацию для этого можно найти здесь .

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