当我使用Scala 2.11.1和Akka 2.3.4编译以下代码时,我得到错误:
Error:(24, 35) Parameter type in structural refinement may not refer to an abstract type defined outside that refinement
def behavior(list: List[T], ele: T):Receive={
^
Error:(24, 35) Parameter type in structural refinement may not refer to a type member of that refinement
def behavior(list: List[T], ele: T):Receive={
^
代码:
package exp
import akka.actor.{ActorSystem, Props, Actor}
trait myTrait[T <: myTrait[T]]{
def computeDistance(that: T): Double
}
class otherClass[T <: myTrait[T]](){
def func(data: List[T]):List[String]={
val system = ActorSystem()
system.actorOf(Props(new Actor{
case object START
case class Job(e1: T, e2: T)
def receive = {
case START =>
context become behavior(data.tail, data.head)
}
def behavior(list: List[T], ele: T):Receive={
case _ =>
sender ! Job(list.head, ele)
context become behavior(list.tail, ele)
}
}))
List.empty[String]
}
}
object Test {
class myClass(val x:Double) extends myTrait[myClass]{
override def computeDistance(that: myClass): Double = this.x - that.x
}
def main(args: Array[String]){
val fc = new otherClass[myClass]()
fc.func(List.empty[myClass])
}
}
我将myTrait定义为myTrait [T&lt ;:myTrait [T]]的原因是我想要myTrait的子类可以用子类参数覆盖computeDistance方法。遵循此post。
otherClass提供了一个方法func,用于在myClass实例列表上生成一些计算。 (实际上上面的代码是我需要的抽象。)
在行为上添加泛型类型可以消除上述错误,但会导致新的错误。
def behavior[S](list: List[T], ele: S):Receive={
case _ =>
sender ! Job(list.head, ele)
context become behavior(list.tail, ele)
}
然后,在Job(list.head,ele)中,类型S的元素不匹配类型为T。
如何解决这个问题?
答案 0 :(得分:4)
class otherClass[T <: myTrait[T]](){
def func(data: List[T]):List[String]={
val system = ActorSystem()
class FooActor extends Actor {
case object START
case class Job(e1: T, e2: T)
def receive = {
case START =>
context become behavior(data.tail, data.head)
}
def behavior(list: List[T], ele: T):Receive={
case _ =>
sender ! Job(list.head, ele)
context become behavior(list.tail, ele)
}
}
system.actorOf(Props(new FooActor))
List.empty[String]
}
}
通过将其作为新类包装
来获取structural
actor的创建
答案 1 :(得分:3)
添加类型注释以将类型扩展为普通Actor
可解决问题:
system.actorOf(Props(new Actor{
// ...
}: Actor))
答案 2 :(得分:1)
为行为方法添加泛型类型:
def behavior[T](map: HashMap[Int, List[T]], list: List[(T, Int)], ele: T):Receive={
case _ =>
}
https://issues.scala-lang.org/browse/SI-1906 由于在运行时缺少类型信息,因此无法使用结构类型外定义的抽象类型。 请检查此答案Using Scala structural types with abstract types。