2015-09-06 2 views
3

Я хотел бы динамически вставить параметр типа, то есть List[T], где T можно найти только во время выполнения.Использовать scala Тип для установки параметра типа (thru TypeTag?)

Как правило, вы можете создавать привязки, если у вас уже есть существующий параметр типа T (не в случае) или во время выполнения с использованием TypeTag s.

Последний звучит как путь, но это меняет вопрос на «как мне получить свой TypeTag здесь».

Я знаю, как создать TypeTag, используя, если у вас есть тип T (typeTag[T]), или если у вас есть экземпляр вашего типа T (см getTypeTag ниже).

Однако у меня нет ни; то, что у меня есть, относится к типу reflect.runtime.universe.Type. Может ли быть возможно преобразовать это в TypeTag, чтобы я мог динамически вставлять свой параметр типа?

Бонусные баллы, если List можно сделать динамичным.

scala> import scala.reflect.runtime.{universe => ru} 

scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T] 

scala> def insertTag[T](tt: ru.TypeTag[T]) = List[T]_ 

scala> val fn = (a: String) => "foo" 
fn: String => String = <function1> 

scala> val pars = getTypeTag(fn).tpe.typeArgs.init(0) 
pars: reflect.runtime.universe.Type = String 

scala> insertTag(pars) 
<console>:21: error: type mismatch; 
found : reflect.runtime.universe.Type 
required: reflect.runtime.universe.TypeTag[?] 
     insertTag(pars) 
       ^
+1

Я не уверен, я понимаю, что ожидаемый результат 'insertTag (Парс)'. Вы всегда ожидаете, что 'fn' будет иметь один параметр или может иметь несколько параметров? Каким будет ожидаемый результат? – Mifeet

+0

Хороший вопрос, думаю, это были биты, которые я пытался упростить. На самом деле я на самом деле получаю 'TypeTag' для' fn.tupled', который выполняет несколько параметров. В действительности вывод не является «List [T]», а «akka.stream.scaladsl.Flow [T]», что полезно так же, как в «List [T]» (поэтому мне пришлось добавить ' _', без него ничего и ошибок). Эта функция 'insertTag' работает, если вы ввели фактический' TypeTag' (т.е. 'insertTag (ru.typeTag [Integer])'), хотя теперь, чтобы заставить его работать только с 'Type', чтобы пройти ... – Tycho

ответ

1

Я не понял, как преобразовать Type в TypeTag. Если ваша цель состоит в том, чтобы получить TypeTag только для параметров функции, вы можете изменить вашу функцию getTypeTag принять функции:

import scala.reflect.runtime.{universe => ru} 
def getTypeTag[T: ru.TypeTag](obj: (T) => Any) = ru.typeTag[T] 
def insertTag[T](tt: ru.TypeTag[T]) = List[T] _ 

val fn = (a: String, b: Int) => "foo" 
var parTypeTag = getTypeTag(fn.tupled) 
insertTag(parTypeTag) // Seq[(String, Int)] => List[(String, Int)] = <function1> 
+0

Hah, nice one :), спасибо! – Tycho