Ссылка на вложенные объекты без полной квалификации - PullRequest
0 голосов
/ 22 марта 2019

У меня есть код (все, что я контролирую), который выглядит следующим образом:

class FirstVeryLongName {
  object ObjectA
  object ObjectB
  object ObjectC
}
class SecondVeryLongName {
  object ObjectB
  object ObjectD
}

Код, который мне нужно написать, эквивалентен

operation1(FirstVeryLongName.ObjectA, FirstVeryLongName.ObjectB)
operation2(SecondVeryLongName.ObjectB, SecondVeryLongName.ObjectD)

... кромечто многократное использование очень длинных имен добавляет много беспорядка.

Вот то, на что я надеялся, что это сработает, но не похоже:

FirstVeryLongName.run {
  operation1(ObjectA, ObjectB)
}

... что яне смог сделать работу, даже если бы я попытался переместить ObjectA и ObjectB в компаньон FirstVeryLongName и написать

FirstVeryLongName.Companion.run { ... }

..., который, как я надеялся, дал бы безусловный доступ кобъекты, как это было бы для val в сопутствующем объекте.

Одна вещь, которую я специально хочу избегать , - это typealiases или импорт их как псевдонимов.Я хочу, чтобы это было очевидно без перекрестных ссылок или ручного просмотра импорта, откуда все это происходит.

Есть ли какой-нибудь трюк, который позволил бы мне написать этот код и написать FirstVeryLongName, ObjectA и ObjectB каждый ровно один раз?

1 Ответ

0 голосов
/ 26 марта 2019

Для меня имеет смысл, что это не работает так, как вы это попробовали.

Само имя класса не является экземпляром и поэтому run или with не применяется. Это то же самое, что просто написать имя пакета и ничего больше. Это тоже не работает.

Что касается подхода Companion, я предполагаю, что вы реализовали следующее:

class FirstVeryLongName {
  companion object {
    object ObjectA
    object ObjectB
    object ObjectC
  }
}

и использование, такое как:

with(FirstVeryLongName.Companion) {
  operation1(ObjectA, ObjectB)
}

На самом деле это может работать, если у вас есть такие свойства, определенные для компаньона (это относится и к функциям). На самом деле это тоже то, что вы упомянули сами. Возможно, вы захотите взглянуть на сгенерированный байт-код, чтобы увидеть, что на самом деле соответствует object, если вы этого еще не сделали. Если вы это сделали, вы можете пропустить оставшуюся часть этого абзаца ;-) Думайте об этом, как будто это просто вложенные классы. Таким образом, в приведенном выше примере у нас есть 3 вложенных класса внутри Companion -класса, который находится внутри FirstVeryLongName -класса.

От Котлина доступ к синглтонному полю INSTANCE скрыт от вас. В коде Kotlin FirstVeryLongName.Companion.ObjectA может представлять как тип, так и ссылку на экземпляр экземпляра. Контекст актуален.

Поскольку вы не можете использовать только имена классов или часть оператора импорта в run / with, вы также не можете упростить доступ к экземпляру singleton таким образом.

Однако вы можете сделать что-то следующим образом. Примечание: я явно не рекомендую этот подход как есть (я не верю, что вам действительно нужны оба: object и val). Может быть, вы также можете использовать выражение объекта там? Скорее всего, есть более простой способ структурировать ваш код, но без соответствующего контекста я могу только догадываться ... я могу ошибаться):

class FirstVeryLongName {
  companion object {
    val ObjectA = FirstVeryLongName.ObjectA // can you use an object expression here?
    val ObjectB = FirstVeryLongName.ObjectA
    val ObjectC = FirstVeryLongName.ObjectA
  }
  object ObjectA
  object ObjectB
  object ObjectC
}

Теперь run / with работает так, как вы хотите, но теперь он фактически обращается к val -референции, которая указывает на object:

with(FirstVeryLongName.Companion) {
  operation1(ObjectA, ObjectB)
}

Просто показывает простой пример с использованием выражения объекта. Вы можете хотеть иметь общий суперкласс, интерфейс или, если вы не возражаете, можете даже использовать object : Any() здесь:

class FirstVeryLongName {
  companion object {
    val ObjectA = object : interfaces.ObjectA  { /* ... */ }
    // ...
  }
}

Использование по-прежнему выглядит так же. Теперь может отличаться только подпись operation1.

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