在Scala的构造函数中扩展具有隐式参数的类的惯用方式是什么?

问题描述 投票:3回答:1

我正在扩展一个抽象类,该抽象类在其构造函数中定义了一个隐式参数。

似乎有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个隐式对象,一个在父类中,一个在子类中。因为它们将始终是同一个对象,这会产生任何效果吗?是出于任何原因我都应该避免的第二种模式吗?

基本上,这里是否有“正确”的模式,或者所有这些都可以接受,取决于使用它们的代码的上下文?

scala implicit
1个回答
2
投票

如果您认为Second的任何用户通常都希望隐式传递a,则[选项3是最佳选择。他们总是可以走显式路线,但是您只是要使它更难一点,并且really显式。我认为这很好,这确实是最常见的模式。

如果不控制Base的定义方式,并且希望用户在每种情况下始终始终显式传递a,则选项1是正确的选择。

选项2永远不会有什么好处,因为您永远都不会以这种方式隐式地传递a,而且,与选项1相比,它的读取更加混乱。请注意以下不编译

implicit val a: AType = ???
val z: Type = ???
new Second(z)
© www.soinside.com 2019 - 2024. All rights reserved.