在 Scala 的构造函数中扩展具有隐式参数的 class 的惯用方法是什么?
What is the idiomatic way to extend a class which has implicit parameters in the constructor in Scala?
我正在扩展一个抽象 class,它在其构造函数中定义了一个隐式参数。
似乎有 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)
也许这取决于 child class 将如何使用。在我的例子中,child class 在范围内不会有隐含的 AType
,所以我倾向于第二个选项。
我对第二个选项最担心的是我现在为同一类型定义了 2 个隐式,一个在 parent class 中,一个在 child class.这有什么影响吗,因为它们总是相同的 object?出于某种原因我应该避免第二种模式吗?
基本上,这里是否有 "right" 模式,或者所有这些模式是否都可以接受,具体取决于它们所使用的代码的上下文?
如果您认为 Second
的任何用户通常希望隐式传递 a
,则选项 3 是最佳选择。他们总是可以走明确的路线,但你只是让它变得更难一点,而且 真的 明确。这在我看来很好,这确实是最常见的模式。
如果您不控制 Base
的定义方式,并且您希望您的用户在任何情况下始终显式传递 a
,那么选项 1 是正确的选择。
选项 2 从来没有任何好处,因为你永远不能那样隐式地传递 a
,而且它比选项 1 读起来更令人困惑。请注意以下 不会编译 。
implicit val a: AType = ???
val z: Type = ???
new Second(z)
我正在扩展一个抽象 class,它在其构造函数中定义了一个隐式参数。
似乎有 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)
也许这取决于 child class 将如何使用。在我的例子中,child class 在范围内不会有隐含的 AType
,所以我倾向于第二个选项。
我对第二个选项最担心的是我现在为同一类型定义了 2 个隐式,一个在 parent class 中,一个在 child class.这有什么影响吗,因为它们总是相同的 object?出于某种原因我应该避免第二种模式吗?
基本上,这里是否有 "right" 模式,或者所有这些模式是否都可以接受,具体取决于它们所使用的代码的上下文?
如果您认为 Second
的任何用户通常希望隐式传递 a
,则选项 3 是最佳选择。他们总是可以走明确的路线,但你只是让它变得更难一点,而且 真的 明确。这在我看来很好,这确实是最常见的模式。
如果您不控制 Base
的定义方式,并且您希望您的用户在任何情况下始终显式传递 a
,那么选项 1 是正确的选择。
选项 2 从来没有任何好处,因为你永远不能那样隐式地传递 a
,而且它比选项 1 读起来更令人困惑。请注意以下 不会编译 。
implicit val a: AType = ???
val z: Type = ???
new Second(z)