在Scala中使用`无法解析符号'错误的通用方法

时间:2014-08-11 17:17:36

标签: scala generics

我需要获得一个通用的检查方法,可以按如下方式使用:

check[Int](10, 1, 5)check[Double](10.0, 1.0, 5.0)

我试过这段代码:

trait RangeChecker {
  def check[T <: AnyVal](value:T, mini:T, maxi:T) : Boolean = {
    (value >= mini && value <= maxi)
  }
}

但是,Cannot resolve symbol>=&&出现<=错误。 什么可能是错的?

enter image description here

3 个答案:

答案 0 :(得分:11)

写作时

def check[T <: AnyVal] ...

您正在为所有 AnyVal的子类型定义方法。 但是,您的实现使用两种方法(<=>=),这两种方法仅适用于类型的子集,即支持排序的方法。

因此,您必须指定该方法适用于排序存在的所有类型,或者换句话说

def check[T](value: T, min: T, max: T)(implicit ev: T => Ordered[T]): Boolean =
  value >= min && value <= max

此语法等同于视图边界(<%

def check[T <% Ordered[T]](value: T, min: T, max: T): Boolean = ...

但是,从view bounds are deprecated开始,你应该避免它。


另一种选择是以这种方式使用Ordering

def check[T](value: T, mini: T, maxi: T)(implicit ord: Ordering[T]): Boolean = {
  import ord.mkOrderingOps
  value >= mini && value <= maxi
}

导入ord.mkOrderingOps后,您可以使用常规>=<=方法。

直接使用上下文绑定的另一个等效替代方法:

def check[T: Ordering](value: T, mini: T, maxi: T): Boolean = {
  val ord = implicitly[Ordering[T]]
  import ord.mkOrderingOps
  value >= mini && value <= maxi
}

答案 1 :(得分:3)

尝试以下方法:

def check[T <% Ordered[T]](value: T, mini: T, maxi: T): Boolean = {
    (value >= mini && value <= maxi)
  }

&lt; =和&gt; =运算符被定义为Ordered trait的一部分,而不是AnyVal。

编辑:请参阅scala API文档herehere

EDIT2:将&lt;:替换为&lt;%

答案 2 :(得分:3)

AnyVal不需要支持>=等操作。这就是为什么它不会像你试过的那样起作用。不幸的是,所有可订购的AnyVal都没有超类。

您应该使用Ordering代替:

def check[T](value: T, low: T, high: T)(implicit ord: Ordering[T]): Boolean = {
  ord.gteq(value, low) && ord.lteq(value, high)
}

当您调用它时,通常不需要明确定义类型T

scala> check(1, 2, 3)
res0: Boolean = false
scala> check(3, 2, 3.5)
res1: Boolean = true