Во-первых, я знаю о https://discuss.kotlinlang.org/t/inline-methods-in-interfaces/1630,, но я хотел бы получить совет о том, как лучше обойти ограничения, и если этот шаблон имеет смысл в целом.
У меня есть Thing
:
interface Thing
У меня также есть служба, связанная с Spring или чем-то еще:
class ThingService {
fun doStuffOn(thing: Thing) {}
inline fun <reified T> doTypeStuffOn(thing: Thing) {}
}
Теперь я действительно хотел бы сказать something.doStuff()
, а не thingService.doStuffOn(thing)
. Итак, я создаю вспомогательный интерфейс:
interface ThingServiceHelper {
val service: ThingService
fun Thing.doStuff() = service.doStuffOn(this)
}
Fantastic! Теперь, если я реализую этот интерфейс, я могу сделать Thing.doStuff()
, и я очень счастлив ...
... пока я не хочу звонить doTypeStuff
таким образом. Я пытаюсь, по логике, добавить его в интерфейс:
inline fun <reified T> Thing.doTypeStuffOn() = context.doTypeStuffOn<T>(this)
Но нет. 'inline' modifier is not allowed on virtual members.
-_-
Мне нравится этот шаблон, и он действительно полезен для имеющегося у меня варианта использования. И, конечно, я могу сделать interface
abstract class
, но я действительно не хочу, потому что вещи, которые его реализуют, уже имеют базовый класс, который не имеет к этому никакого отношения, и интерфейсы в целом более гибкие.
Я не могу переместить функцию за пределы интерфейса, поскольку она зависит от абстрактного члена service
внутри интерфейса. Хмм. Есть мысли по этому поводу? Почему я не могу добавить встроенные функции extension в интерфейс? Они не участники! Что за черт. По крайней мере, я хотел бы понять соображения языкового дизайна здесь.