将隐式引入范围
Bring implicit to scope
我有一个特点
trait Tr{
def logic: Option[() => Unit] = None
def apply(): Unit = logic match {
case Some(l) => l()
case None =>
}
}
object Tr{
implicit def procLogic2Opt(processingLogic: () => Unit): Option[() => Unit]
= Some(processingLogic)
}
问题是在对特征进行子类化时,我必须显式导入 Tr._
以将隐含项引入范围。像这样
import Tr._ //otherwise does not compile
class Trrr extends Tr{
override def processingLogic = () => println("test")
}
有没有不用显式导入的方法?我该如何重新设计它?
回答标题问题,如果你真的真的真的需要它,把你的隐式移到特征:
trait Tr{
implicit def procLogic2Opt(...) = ...
}
虽然这并不总是一个好的做法,因为很难找到哪个隐式负责。
一个故事:在我之前的项目中,我们在任何地方都继承了具有隐式(某种)T => Any
的日志记录特征 - 想象一下我们有多少意想不到的类型转换。 () => Unit
也是如此,因为很多人可能会继承你的特质,甚至不知道你的隐式,并且想知道为什么 apply
以外的功能在它们不应该工作的时候工作。
除了隐式转换(如您的 procLogic2Opt
)之外,也是一种不良做法(几乎总是如此)。
引自here:
Do not use implicits to do automatic conversions between similar
datatypes (for example, converting a list to a stream); these are
better done explicitly because the types have different semantics, and
the reader should beware of these implications.
更准确地说你的情况:Scala Option implicit conversion - Bad practice or missing feature?
改用implicit-classes:
implicit class RichSomething(something: Something){
def toSomethingElse = ...
}
something.toSomethingElse
如评论中所述,您的情况更简单
Some(() => println("aaaa"))
class Trrr extends Tr{
override def logic = Some(() => println("test"))
}
这将为您提供明确的、易于理解和发现的类型,而不用想知道 () => Unit
是如何变成 Option[() => Unit]
Because the client is supposed to call only apply. I thought it's not necessary for subclassers to know that Option is required
那么,为什么需要它?
trait Tr {
protected val logic: () => Unit = () => {}
def apply(): Unit = logic()
}
class Trrr extends Tr{
override val logic = () => println("test")
}
(val logic
以避免每次都重新创建它。)
我有一个特点
trait Tr{
def logic: Option[() => Unit] = None
def apply(): Unit = logic match {
case Some(l) => l()
case None =>
}
}
object Tr{
implicit def procLogic2Opt(processingLogic: () => Unit): Option[() => Unit]
= Some(processingLogic)
}
问题是在对特征进行子类化时,我必须显式导入 Tr._
以将隐含项引入范围。像这样
import Tr._ //otherwise does not compile
class Trrr extends Tr{
override def processingLogic = () => println("test")
}
有没有不用显式导入的方法?我该如何重新设计它?
回答标题问题,如果你真的真的真的需要它,把你的隐式移到特征:
trait Tr{
implicit def procLogic2Opt(...) = ...
}
虽然这并不总是一个好的做法,因为很难找到哪个隐式负责。
一个故事:在我之前的项目中,我们在任何地方都继承了具有隐式(某种)T => Any
的日志记录特征 - 想象一下我们有多少意想不到的类型转换。 () => Unit
也是如此,因为很多人可能会继承你的特质,甚至不知道你的隐式,并且想知道为什么 apply
以外的功能在它们不应该工作的时候工作。
除了隐式转换(如您的 procLogic2Opt
)之外,也是一种不良做法(几乎总是如此)。
引自here:
Do not use implicits to do automatic conversions between similar datatypes (for example, converting a list to a stream); these are better done explicitly because the types have different semantics, and the reader should beware of these implications.
更准确地说你的情况:Scala Option implicit conversion - Bad practice or missing feature?
改用implicit-classes:
implicit class RichSomething(something: Something){
def toSomethingElse = ...
}
something.toSomethingElse
如评论中所述,您的情况更简单
Some(() => println("aaaa"))
class Trrr extends Tr{
override def logic = Some(() => println("test"))
}
这将为您提供明确的、易于理解和发现的类型,而不用想知道 () => Unit
是如何变成 Option[() => Unit]
Because the client is supposed to call only apply. I thought it's not necessary for subclassers to know that Option is required
那么,为什么需要它?
trait Tr {
protected val logic: () => Unit = () => {}
def apply(): Unit = logic()
}
class Trrr extends Tr{
override val logic = () => println("test")
}
(val logic
以避免每次都重新创建它。)