Какой идиоматический способ расширения класса, который имеет неявные параметры в конструкторе в Scala? - PullRequest
4 голосов
/ 07 октября 2019

Я расширяю абстрактный класс, который определяет неявный параметр в его конструкторе.

Кажется, что есть 3 различных способа сделать это:

abstract class Base(z: ZType)(implicit a: AType)

// Explicit
class First(z: ZType, a: Atype) extends Base(z)(a)

// Explicitly pass a into the child class which
// implicitly passes it into the parent class
class Second(z: ZType, implicit val a: AType) extends Base(z)

// Implicitly passed into both
class Third(z: ZType)(implicit a: AType) extends Base(z)

Возможно, это зависит от того, какдочерний класс будет использоваться. В моем случае у дочернего класса не будет неявной области действия AType, поэтому я склонялся ко второму варианту.

Моя самая большая проблема со вторым вариантом состоит в том, что у меня теперь есть 2 имплицита, определенные длятого же типа, один в родительском классе и один в дочернем классе. Имеет ли это какой-либо эффект, поскольку они всегда будут одним и тем же объектом? Является ли второй шаблон тем, который мне следует избегать по какой-либо причине?

По сути, здесь есть «правильный» шаблон или все они приемлемы в зависимости от контекста кода, в котором они используются?

1 Ответ

4 голосов
/ 08 октября 2019

Вариант 3 является лучшим, если вы думаете, что любой пользователь Second обычно хочет передать a неявно. Они всегда могут пойти по явному пути, но вы просто усложняете это, а действительно явно. На мой взгляд, это хорошо, и это действительно самый распространенный шаблон.

Вариант 1 - это правильный вызов, если вы не контролируете, как определяется Base, и вы хотите, чтобы ваши пользователи всегда передавали a явно в каждом случае.

Вариант 2 никогда не бывает хорошим, потому что вы никогда не можете пропустить a неявным образом таким образом, и читать его будет просто более запутанно, чем вариант 1. Обратите внимание, что следующий не компилирует .

implicit val a: AType = ???
val z: Type = ???
new Second(z)
...