如何在Scala中编写一个可以处理多个参数类型的服务?
我正在设计一个API。基本上是这样的:如何在Scala中编写一个可以处理多个参数类型的服务?,scala,types,typeclass,type-systems,type-level-computation,Scala,Types,Typeclass,Type Systems,Type Level Computation,我正在设计一个API。基本上是这样的: trait Service { def performUseCase[T](transferObjects: Iterable[TransferObject[T]]) } trait TransferObject[T] { def data: T } case class TransferObjectA[T](data: T) extends TransferObject[T] case class TransferObject
trait Service {
def performUseCase[T](transferObjects: Iterable[TransferObject[T]])
}
trait TransferObject[T] {
def data: T
}
case class TransferObjectA[T](data: T) extends TransferObject[T]
case class TransferObjectB[T](data: T) extends TransferObject[T]
注意:如有必要,我可以更改TransferObject
s的实现。语义上重要的是:
TransferObject
sSeq[TransferObject[\u]
,或者一个传输对象引用下一个或多个对象服务
特性实现。对于每个服务
实例,必须指定此实例可以处理的类型。
示例:此服务val myService=myService()
可以处理TransferObjects[MyTypeA]
和TransferObjects[MyTypeB]
等。当API用户试图传递TransferObjects[MyUnknownType]
时,编译器应抛出错误
我读过Scala的类型系统,类型类(比如隐式)和类型声明,但我还不了解所有细节
我尝试使用服务
特性的实现,将特定于类型的处理程序作为类型类。MyHandler[MyTypeA]
,MyHandler[MyTypeB]
等,并使用implicits为当前参数类型传入正确的处理程序。但是处理程序不应向API用户公开。这就是为什么我想知道,如果用户传入服务
无法处理的类型的参数,是否可能引发编译器错误
真正的实现更复杂,而且目前还不完善。也许我可以稍后再交付一些代码
综述: 同样:我需要多个服务实例。每个实例都应该能够处理多个参数类型。如果传入未知类型的参数,编译器应该抛出一个错误。特定类型的处理程序被视为实现细节,应该对API用户保持隐藏
我如何认识到这一点?您可以使用
密封的trait TransferObject[T]{…
和案例类TransferObjectA(数据:Int)扩展TransferObject[Int]…
和def performUseCase[T](transferObjects:Iterable[TransferObject[T]])
的内部
transferObject match{
case TransferObjectA(myInt) => ...
...
}//throws warning because of unmatched TransferObjectB on compile time because of sealed trait
还可以查看您可以使用
密封的trait TransferObject[T]{…
和案例类TransferObjectA(数据:Int)扩展TransferObject[Int]…
和def performUseCase[T](transferObjects:Iterable[TransferObject[T]])
的内部
transferObject match{
case TransferObjectA(myInt) => ...
...
}//throws warning because of unmatched TransferObjectB on compile time because of sealed trait
还可以看看这里有一个基于类型类的方法:
trait TransferObject[T] {
def data: T
}
case class TransferObjectA[T](data: T) extends TransferObject[T]
case class TransferObjectB[T](data: T) extends TransferObject[T]
trait Service {
protected[this] trait Handler[A] {
def apply(objs: Iterable[TransferObject[A]]): Unit
}
def performUseCase[A](objs: Iterable[TransferObject[A]])(
implicit handler: Handler[A]
) = handler(objs)
}
然后:
object MyIntAndStringService extends Service {
implicit object intHandler extends Handler[Int] {
def apply(objs: Iterable[TransferObject[Int]]) {
objs.foreach(obj => printf("Int: %d\n", obj.data))
}
}
implicit object stringHandler extends Handler[String] {
def apply(objs: Iterable[TransferObject[String]]) {
objs.foreach(obj => printf("String: %s\n", obj.data))
}
}
}
val ints = List(1, 2, 3).map(TransferObjectA(_))
val strings = List("A", "B", "C").map(TransferObjectA(_))
val chars = List('a', 'b', 'c').map(TransferObjectA(_))
最后:
scala> MyIntAndStringService.performUseCase(ints)
Int: 1
Int: 2
Int: 3
scala> MyIntAndStringService.performUseCase(strings)
String: A
String: B
String: C
scala> MyIntAndStringService.performUseCase(chars)
<console>:14: error: could not find implicit value for parameter handler: MyIntAndStringService.Handler[Char]
MyIntAndStringService.performUseCase(chars)
^
scala>MyIntAndStringService.performUseCase(ints)
内部:1
内部:2
内部:3
scala>MyIntAndStringService.performUseCase(字符串)
字符串:A
字符串:B
字符串:C
scala>MyIntAndStringService.performUseCase(chars)
:14:错误:找不到参数处理程序MyIntAndStringService.handler[Char]的隐式值
MyIntAndStringService.performUseCase(chars)
^
根据需要。这里有一种基于类型类的方法:
trait TransferObject[T] {
def data: T
}
case class TransferObjectA[T](data: T) extends TransferObject[T]
case class TransferObjectB[T](data: T) extends TransferObject[T]
trait Service {
protected[this] trait Handler[A] {
def apply(objs: Iterable[TransferObject[A]]): Unit
}
def performUseCase[A](objs: Iterable[TransferObject[A]])(
implicit handler: Handler[A]
) = handler(objs)
}
然后:
object MyIntAndStringService extends Service {
implicit object intHandler extends Handler[Int] {
def apply(objs: Iterable[TransferObject[Int]]) {
objs.foreach(obj => printf("Int: %d\n", obj.data))
}
}
implicit object stringHandler extends Handler[String] {
def apply(objs: Iterable[TransferObject[String]]) {
objs.foreach(obj => printf("String: %s\n", obj.data))
}
}
}
val ints = List(1, 2, 3).map(TransferObjectA(_))
val strings = List("A", "B", "C").map(TransferObjectA(_))
val chars = List('a', 'b', 'c').map(TransferObjectA(_))
最后:
scala> MyIntAndStringService.performUseCase(ints)
Int: 1
Int: 2
Int: 3
scala> MyIntAndStringService.performUseCase(strings)
String: A
String: B
String: C
scala> MyIntAndStringService.performUseCase(chars)
<console>:14: error: could not find implicit value for parameter handler: MyIntAndStringService.Handler[Char]
MyIntAndStringService.performUseCase(chars)
^
scala>MyIntAndStringService.performUseCase(ints)
内部:1
内部:2
内部:3
scala>MyIntAndStringService.performUseCase(字符串)
字符串:A
字符串:B
字符串:C
scala>MyIntAndStringService.performUseCase(chars)
:14:错误:找不到参数处理程序MyIntAndStringService.handler[Char]的隐式值
MyIntAndStringService.performUseCase(chars)
^
如所愿