接近分裂特征的正确方法
Correct way to approach splitting a trait
我有3个特质:
trait Worker
...
trait StringWorker extends Worker {
def workString(): Iterator[String]
}
...
trait IntWorker extends Worker {
def workInt(): Iterator[Int]
}
我的一些 类 仅扩展 StringWorker
,而其他的则同时扩展 StringWorker
和 IntWorker
我的代码根据某些模式匹配获得正确的解析器,如下所示:
def getCorrectWorkerProvider: () => Worker = {
case SomeCase => getStringWorkerProvider()
case _ => getIntWorkerProvider()
}
如果我保持与上面写的相同的特征,那么我几乎总是不得不做这样的伪代码:
if working with string, then getCorrectWorkerProvider().asInstanceOf[StringWorker].workString
if working with int, then getCorrectWorkerProvider().asInstanceOf[IntWorker].workInt
而如果我将特征的定义更改为如下内容:
trait Worker {
def workString(): Iterator[String]
def workInt(): Iterator[Int]
}
trait StringWorker extends Worker
trait IntWorker extends Worker
那么我将永远不必使用 .asInstanceOf[SomeWorker]
来调用正确的方法。
我认为第一种方式更正确和直观,因为这些方法是特定于某个 Worker 的,但是第二种方式似乎不那么令人头疼。
我相信您正在寻找的是类型类模式。 Here's an article that explains the idea。基本上它的工作方式是创建一个函数,该函数接受类型 T
的值和隐式参数 Worker[T]
,然后 scala 的隐式解析机制为您找到正确的 Worker[T]
.
这是一个例子:
object Main {
def main(args: Array[String]): Unit = {
work("String")
work(3)
}
def work[T](value: T)(implicit worker: Worker[T]) = {
worker.work(value)
}
}
trait Worker[T]{
def work(t: T): Iterator[T]
}
object Worker {
implicit val stringWorker: Worker[String] = (t: String) => Iterator(t)
implicit val intWorker: Worker[Int] = (t: Int) => Iterator(t)
}
我有3个特质:
trait Worker
...
trait StringWorker extends Worker {
def workString(): Iterator[String]
}
...
trait IntWorker extends Worker {
def workInt(): Iterator[Int]
}
我的一些 类 仅扩展 StringWorker
,而其他的则同时扩展 StringWorker
和 IntWorker
我的代码根据某些模式匹配获得正确的解析器,如下所示:
def getCorrectWorkerProvider: () => Worker = {
case SomeCase => getStringWorkerProvider()
case _ => getIntWorkerProvider()
}
如果我保持与上面写的相同的特征,那么我几乎总是不得不做这样的伪代码:
if working with string, then getCorrectWorkerProvider().asInstanceOf[StringWorker].workString
if working with int, then getCorrectWorkerProvider().asInstanceOf[IntWorker].workInt
而如果我将特征的定义更改为如下内容:
trait Worker {
def workString(): Iterator[String]
def workInt(): Iterator[Int]
}
trait StringWorker extends Worker
trait IntWorker extends Worker
那么我将永远不必使用 .asInstanceOf[SomeWorker]
来调用正确的方法。
我认为第一种方式更正确和直观,因为这些方法是特定于某个 Worker 的,但是第二种方式似乎不那么令人头疼。
我相信您正在寻找的是类型类模式。 Here's an article that explains the idea。基本上它的工作方式是创建一个函数,该函数接受类型 T
的值和隐式参数 Worker[T]
,然后 scala 的隐式解析机制为您找到正确的 Worker[T]
.
这是一个例子:
object Main {
def main(args: Array[String]): Unit = {
work("String")
work(3)
}
def work[T](value: T)(implicit worker: Worker[T]) = {
worker.work(value)
}
}
trait Worker[T]{
def work(t: T): Iterator[T]
}
object Worker {
implicit val stringWorker: Worker[String] = (t: String) => Iterator(t)
implicit val intWorker: Worker[Int] = (t: Int) => Iterator(t)
}