Сравнение шаблонов с генериками - PullRequest
3 голосов
/ 20 марта 2011

Учитывая следующее соответствие шаблону класса:

clazz match {
  case MyClass => someMethod[MyClass]
}

Можно ли ссылаться на MyClass в общем виде, основываясь на том, что было найдено в соответствии с шаблоном? Например, если у меня есть несколько подклассов MyClass, могу ли я написать простое сопоставление с шаблоном, чтобы передать сопоставленный тип в someMethod:

clazz match {
  case m <: MyClass => someMethod[m]
}

Ответы [ 2 ]

7 голосов
/ 20 марта 2011

К сожалению, в Скале типы не являются первоклассными гражданами.Это означает, например, что вы не можете выполнять сопоставление с образцом для типов.Большая часть информации теряется из-за глупого стирания типа, унаследованного от платформы Java.

Я не знаю, есть ли какие-либо запросы на улучшение для этого, но это одна из худших проблем в моем варианте, поэтомукто-то должен действительно выдвинуть такой запрос.

Правда в том, что вам нужно будет передавать параметры доказательств, в лучшем случае в форме неявных параметров.

Лучшее, что я могу придумать, - этов строке

class PayLoad

trait LowPriMaybeCarry {
   implicit def no[C] = new NoCarry[C]
}
object MaybeCarry extends LowPriMaybeCarry {
   implicit def canCarry[C <: PayLoad](c: C) = new Carry[C]
}

sealed trait MaybeCarry[C]
final class NoCarry[C] extends MaybeCarry[C]
final class Carry[C <: PayLoad] extends MaybeCarry[C] {
   type C <: PayLoad
}

class SomeClass[C <: PayLoad]

def test[C]( implicit mc: MaybeCarry[C]) : Option[SomeClass[_]] = mc match {
   case c: Carry[_] => Some(new SomeClass[ c.C ])
   case _ => None
}

но все же я не могу получить последствия для работы:

test[String]
test[PayLoad]  // ouch, not doin it
test[PayLoad](new Carry[PayLoad])  // sucks

Так что, если вы хотите уберечь себя от серьезного повреждения мозга, я бы забыл опроект или искать другой язык.Может, Хаскел лучше здесь?Я все еще надеюсь, что мы в конечном итоге сможем сопоставлять типы, но мои надежды довольно низки.

Может быть, ребята из scalaz придумали решение, они в значительной степени использовали систему типов Scala до предела.

0 голосов
/ 21 сентября 2011

Ваш код не совсем понятен, потому что, по крайней мере, в java clazz - это типичное имя для переменных типа java.lang.Class и вариаций.Я до сих пор считаю, что clazz - это не экземпляр Class, а ваш собственный класс.

В Java и Scala, учитывая объект o: AnyRef, вы можете получить доступ к его классу во время выполнения через o.getClass: Class[_] и, например, создавать экземпляры этого класса через API Reflection.Однако параметры типа передаются во время компиляции, поэтому вы не можете передавать тип как есть во время компиляции.Либо вы используете AnyRef повсеместно в качестве типа (который будет работать, я полагаю), либо вы используете API отражения, если у вас есть более сложные потребности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...