Привести объекты к сопоставимому типу - PullRequest
3 голосов
/ 28 мая 2011

в Скале. У меня есть два объекта типа Any. Если это возможно, я бы хотел привести объекты к правильной характеристике Ordered, а затем сравнить их с методом <. В противном случае я хочу выбросить исключение. Должно быть просто, но я в тупике ... </p>

Ответы [ 2 ]

6 голосов
/ 28 мая 2011

Вы можете реализовать это с Ordering классом типа:

def compare[T : Ordering : Manifest](a: AnyRef, b: AnyRef) = {
    val c = manifest[T].erasure

    if (c.isAssignableFrom(a.getClass) && c.isAssignableFrom(b.getClass))
        implicitly[Ordering[T]].compare(a.asInstanceOf[T], b.asInstanceOf[T]) 
    else 
        throw new IllegalArgumentException("Wrong argument type")
}

А затем используйте это так:

compare[Date](new Date, new Date)
compare[String]("A", "B") 

Но этот код выдаст IllegalArgumentException:

compare[Date]("A", "B") 

Обновление

Если вы действительно не знаете типы объектов, которые вы пытаетесь сравнить, тогда вы можете использовать это решение:

def compare(a: AnyRef, b: AnyRef) = {
  val c = classOf[Comparable[_]]

  if (c.isAssignableFrom(a.getClass) && c.isAssignableFrom(a.getClass) && a.getClass == b.getClass) {
    a.asInstanceOf[Comparable[AnyRef]].compareTo(b.asInstanceOf[Comparable[AnyRef]])
  } else {
    throw new IllegalArgumentException("Incopatible argument types: " + a.getClass.getName + " and " + b.getClass.getName)
  }
}

Это относится к интерфейсу Comparable Java. Обычно в scala есть 2 черты для этой цели:

  • Ordred - аналогично Comparable, но существующие классы (например, String или Date) не реализуют его, поэтому вы не можете проверить его во время выполнения (по крайней мере, для этих классов)
  • Ordering - это класс типов, и вы не можете получить его во время выполнения.

С другой стороны, Ordered расширяет интерфейс Comparable, поэтому это решение также должно работать для всех классов, которые расширяют Ordered.

0 голосов
/ 28 мая 2011

Как насчет этого?

scala> (i, j) match {                                  
     | case (a: Ordered[Any], b: Ordered[Any]) => a < b
     | case _ => throw new RuntimeException            
     | } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...