2015-02-03 2 views
1

Как я могу сделать совпадение шаблона над reflect.runtime.universe.Type?Scala: соответствие шаблону по сравнению с изображением.runtime.universe.Type?

def test(t: reflect.runtime.universe.Type) { 
    t match { 
    case Int => \\ ... 
    case Double => \\ ... 
    case String => \\ ... 
    case _ => \\ ... 
    } 
}  

Это dosn't работу, как переводчик жалуется:

error: pattern type is incompatible with expected type; 
found : Int.type 
required: reflect.runtime.universe.Type 
Note: if you intended to match against the class, try `case _: Int` 
     case Int => // ... 
      ^

Попытка предложение не работает, либо:

def test(t: reflect.runtime.universe.Type) { 
    t match { 
    case _: Int => \\ ... 
    case _: Double => \\ ... 
    case _: String => \\ ... 
    case _ => \\ ... 
    } 
}  

... 

error: pattern type is incompatible with expected type; 
found : Int 
required: reflect.runtime.universe.TypeApi 
      case _: Int => // ... 
       ^

Так что правильный синтаксис для этого?

Спасибо!

+0

пс .: Используя If- заявление, я могу сделать следующее: если (т == reflect.runtime.universe.typeOf [String]) // ... Это, однако, не работает в совпадающим синтаксисе шаблона: т матча { case reflect.runtime.universe.typeOf [String] => \\ ... случай _ => } Я получаю ошибку намек: тип TYPEOF не является членом scala.reflect.api.JavaUniverse случае reflect.runtime.universe.typeOf [String] => fieldMap (pName) .set (pVal) –

+0

И еще одна проблема: выполнение if-утверждения Я нахожу, что scala.Int явно не совпадает с Int. Однако результат reflection.runtime.universe.typeOf [scala.Int]) является Int, а результат (t == reflect.runtime.universe.typeOf [Int]) является ложным, а также результатом if (т == reflect.runtime.universe.typeOf [scala.Int]). Как это решить? –

+1

Вам нужен стабильный идентификатор для сопоставления шаблонов, если не используется 'if', и вы хотите использовать' =: = ', а не' == '. Попробуйте 'case t, если t =: = typeOf [String] => ...' – lmm

ответ

-1

Ok, я нашел обходной путь:

def test(t: reflect.runtime.universe.Type) { 
    t.toString match { 
    case "Int" => \\ ... 
    case "scala.Int" => \\ ... 
    case "Double" => \\ ... 
    case "scala.Double" => \\ ... 
    case "String" => \\ ... 
    case _ => \\ ... 
    } 
} 

Однако, есть лучшее решение, которое уклоняется происходит с помощью строки?

0

Как указано в lmm и n1r3, вам может быть лучше использовать, если здесь. Тем не менее, вы могли бы сделать что-то вроде следующего:

import reflect.runtime.universe._ 
case class TypeComparer[A](typeToCompare: TypeTag[A]){ 
    def unapply(universeType: Type) = universeType =:= typeToCompare.tpe 
} 

object TypeComparer{ 
    val IntComparer = new TypeComparer(typeTag[Int]) 
} 

object TestObject{ 
    def tester(t: Type) { 
    t match { 
     case TypeComparer.IntComparer() => println("pass") 
     case _ => println("fail") 
    } 
    } 

    def test[A](implicit ev: TypeTag[A]) = tester(typeOf[A]) 
} 

, который вы можете запустить как:

TestObject.test[Int] //pass 
TestObject.test[Boolean] //fail 

Недостатком является то, что вам нужно создать конкретный объект для каждого компаратором, как я не знаю способ иметь сопутствующий объект с типом, используемым в apply

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

2

TypeTag API имеет оператор =:= сравнения и метод получения экземпляра Type для данного класса, вы можете комбинировать их с охранниками, чтобы получить желаемый результат:

import scala.reflect.runtime.universe._ 

def test(t: Type) { 
    t match { 
    case t if t =:= typeOf[Int] => println("int") 
    case t if t =:= typeOf[String] => println("string") 
    case _ => 
    } 
} 
Смежные вопросы