Scala类型不匹配:需要_ $ 1,其中类型_ $ 1 <:< [英] Scala type mismatch: required _$1 where type _$1 &lt;:

查看:255
本文介绍了Scala类型不匹配:需要_ $ 1,其中类型_ $ 1 <:<的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Scala的新手,我面临的是我无法理解和解决的问题。我写了一个通用的 trait 这就是这个:

  trait DistanceMeasure [P<:DbScanPoint] {
def distance(p1:P,p2:P):Double
}

其中 DbScanPoint 很简单:

  trab DbScanPoint扩展Serializable {} 

然后我有以下两个类来扩展它们:

  class Point2d(id:Int,x:Double,y:Double)扩展DbScanPoint {
def getId()= id
def getX()= x
def getY()= y
}

class EuclideanDistance将DistanceMeasure [Point2d]扩展为Serializable {

override def距离(p1:Point2d,p2:Point2d)= {
(p1.getX() - p2.getX())*(p1.getX() - p2.getX())+(p1.getY -p2.getY())*(p1.getY() - p2.getY())
}
}

最后我有这个课程:

  class DBScanSettings {

var distanceMeas ure:DistanceMeasure [_<:DbScanPoint] = new EuclideanDistance
// ...
}

我的问题是,如果当我在我的测试主写这个:

  val dbScanSettings = new DBScanSettings( )
dbScanSettings.distanceMeasure.distance(new Point2d(1,1,1),new Point2d(2,2,2))

我得到下面的编译错误:

  type mismatch; 
[error] found:it.polito.dbdmg.ontic.point.Point2d
[error] required:_ $ 1 where _ $ 1 <:it.polito.dbdmg.ontic.point.DbScanPoint

我无法理解哪个是问题。我和其他类做了一个非常类似的事情,我没有错误,所以这个错误的原因对我来说很晦涩。



有人可以帮我吗? p>

谢谢。

更新



  trait DistanceMeasure {
def distance( p1:DbScanPoint,p2:DbScanPoint):Double
}

显然所有相关你的问题的核心是你正在定义你的 distanceMeasure c> var具有存在类型,所以对于编译器来说类型不是完全已知的。然后,您要调用 distance ,它将采用两个 P <:DbScanPoint 类型的< c $ c> Point2d 实例。现在,这些是 distanceMeasure (新的 EuclideanDistance )后面的具体类的正确类型,但是您定义的方式 distanceMeasure (带有存在),编译器不能强制执行 Point2d 实例是具体底层 DistanceMeasure 需要。



为了说明而不是新的 EuclideanDistance ,您实例化了一个完全不同的< $ c> DistanceMeasure ,它没有使用 Point2d 实例,然后尝试调用 distance he你在这里的方式。如果编译器不能强制底层类接受提供的参数,它会像这样抱怨。

有很多方法可以解决这个问题,而解决方案最终取决于您在班级结构中需要的灵活性。一种可能的方式是这样的:

  trait DBScanSettings [P< ;: DbScanPoint] {
val distanceMeasure:DistanceMeasure [ P]
// ...
}

class Point2dScanSettings extends DBScanSettings [Point2d] {
val distanceMeasure = new EuclideanDistance
}

然后再测试:

  val dbScanSettings = new Point2dScanSettings()
dbScanSettings.distanceMeasure.distance(new Point2d(1,1,1),new Point2d(2,2,2))

但是,如果我没有真正理解你需要什么样的抽象级别,那么定义重构将取决于你。


I'm a newbie to Scala and I'm facing an issue I can't understand and solve. I have written a generic trait which is this one:

trait DistanceMeasure[P<:DbScanPoint] {
  def distance(p1:P, p2:P):Double
}

where DbScanPoint is simply:

trait DbScanPoint extends Serializable {}

Then I have the following two classes extending them:

class Point2d (id:Int, x:Double, y:Double) extends DbScanPoint {
   def getId() = id
   def getX() = x
   def getY() = y
}

class EuclideanDistance extends DistanceMeasure[Point2d] with Serializable {

   override def distance(p1:Point2d,p2:Point2d) = {
      (p1.getX()-p2.getX())*(p1.getX()-p2.getX()) + (p1.getY()-p2.getY()) * (p1.getY()-p2.getY())
  }
}

And at the end I have this class:

class DBScanSettings {

   var distanceMeasure:DistanceMeasure[_<:DbScanPoint] = new EuclideanDistance
   //...
}

My problem is that if that when I write in my test main this:

 val dbScanSettings = new DBScanSettings()
 dbScanSettings.distanceMeasure.distance(new Point2d(1,1,1), new Point2d(2,2,2))

I get the following compiling error:

 type mismatch;
 [error]  found   : it.polito.dbdmg.ontic.point.Point2d
 [error]  required: _$1 where type _$1 <: it.polito.dbdmg.ontic.point.DbScanPoint

I can't understand which is the problem. I have done a very similar thing with other classes and I got no error, so the reason of this error is quite obscure to me.

May somebody help me?

Thanks.

UPDATE

I managed to do what I needed by changing the code to:

trait DistanceMeasure {
  def distance(p1:DbScanPoint, p2:DbScanPoint):Double
}

And obviously making all the related changes.

解决方案

The heart of your problem is that you are defining your distanceMeasure var with an existential type, so to the compiler that type is not completely known. Then, you are calling distance which is to take two instances of type P <: DbScanPoint passing in two Point2d instances. Now, these are the correct types for the concrete class behind distanceMeasure (a new EuclideanDistance), but the way you defined distanceMeasure (with an existential), the compiler cannot enforce that Point2d instances are the right type that the concrete underlying DistanceMeasure takes.

Say for arguments sake that instead of a new EuclideanDistance, you instead instantiated a completely different impl of DistanceMeasure that did not take Point2d instances and then tried to call distance he way you have it here. If the compiler can't enforce that the underlying class accepts the arguments supplied, it's going to complain like this.

There are a bunch of ways to fix this, and the solution ultimately depends on the flexibility you need in your class structure. One possible way is like so:

trait DBScanSettings[P <: DbScanPoint] {
  val distanceMeasure:DistanceMeasure[P]
 //...
}

class Point2dScanSettings extends DBScanSettings[Point2d]{
  val distanceMeasure = new EuclideanDistance
}

And then to test:

val dbScanSettings = new Point2dScanSettings()
dbScanSettings.distanceMeasure.distance(new Point2d(1,1,1), new Point2d(2,2,2))

But without me really understanding you requirements for what levels of abstraction you need, it's going to be up to you to define the restructure.

这篇关于Scala类型不匹配:需要_ $ 1,其中类型_ $ 1 <:<的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆