为什么我可以使用视图绑定而不是上限来比较字符串?

时间:2017-12-05 06:09:15

标签: scala

在以下示例中,我可以使用String但不是view bound来比较两个upper bound,即使在REPL上,<方法适用于String 。是因为String不是Ordered [T]的子类,而是从String到Ordered [String]的隐式转换?

//view bound example. For String, It seems to work because I suppose there is an implicit conversion from String to Ordered[String]
scala> class Person[T <% Ordered[T]](val fn:T, val ln:T){
     | def greater = if(fn > ln) fn else ln
     | }
defined class Person

scala> val p1 = new Person("manu", "chadha")
p1: Person[String] = Person@f95d64d

scala> p1.greater
res0: String = manu

scala> val p2 = new Person("anita", "chadha")
p2: Person[String] = Person@30cafd13

scala> p2.greater
res1: String = chadha

//upper bound example. It doesn't work for String. Is it because String is not a subclass of Ordered[T] but there is an implicit converstion from String to Ordered[Strig]
scala> class Person2[T <: Ordered[T]](val fn:T, val ln:T){
     | def greater = if(fn > ln) fn else ln
     | }
defined class Person2

scala> val p3 = new Person2("manu", "chadha")
<console>:12: error: inferred type arguments [String] do not conform to class Person2's type parameter bounds [T <: Ordered[T]]
       val p3 = new Person2("manu", "chadha")
                ^
<console>:12: error: type mismatch;
 found   : String("manu")
 required: T
       val p3 = new Person2("manu", "chadha")
                            ^
<console>:12: error: type mismatch;
 found   : String("chadha")
 required: T
       val p3 = new Person2("manu", "chadha")
                                    ^

我认为视图边界已被弃用。那么以下示例如何在REPL中工作?

scala> "manu" > "Manu"
res2: Boolean = true

1 个答案:

答案 0 :(得分:2)

完全。 <{1}}被视为

"a" < "b"

其中scala.Predef.augmentString("a") < "b" 是一个StringOps类,也是augmentString("a"),其中Ordered[String]来自。{/ p>

不推荐使用查看边界语法,但隐式转换和参数不是。因此,在现代Scala中编写代码的方式只是使用隐式参数,这也是隐式转换:

<

虽然通常认为使用类型类是最佳做法。在这里,我们在标准库中有class Person[T](val fn:T, val ln:T)(implicit view: T => Ordered[T]){ def greater = if(fn > ln) fn else ln }

scala.math.Ordering

其中包含不被弃用的语境形式的语法形式:

import Ordering.Implicits._ // brings operators like "<" into the scope

class Person[T](val fn: T, val ln: T)(implicit val order: Ordering[T]) {
  def greater = if (fn > ln) fn else ln
}

这相当于Java的import Ordering.Implicits._ // brings operators like "<" into the scope class Person[T: Ordering](val fn: T, val ln: T) { def greater = if (fn > ln) fn else ln } vs Comparable,除非您不必手动传递Comparator个实例

Comparator