Для меня имеет смысл, что это не работает так, как вы это попробовали.
Само имя класса не является экземпляром и поэтому 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
.