2013-05-09 3 views
2

У меня есть класс, который принимает функциюScala отражение в именах параметров функции

case class FunctionParser1Arg[T, U](func:(T => U)) 

def testFunc(name1:String):String = name1 
val res = FunctionParser1Arg(testFunc) 

Я хотел бы знать информацию типа подписи на функции из внутри класса корпуса. Я хочу знать имя и тип параметра. У меня был успех в поиске типа с использованием зеркальных объектов времени исполнения, но не с именем. Какие-либо предложения?

+0

Было бы полезно, если бы вы описали, что у вас есть, поскольку «путь» оттуда к тому, что вы хотите, возможно, был короче в ответе. –

ответ

14

Хорошо, предположим, что вы получили символ для экземпляра func указывает на:

import scala.reflect.runtime.universe._ 
import scala.reflect.runtime.{currentMirror => m} 

val im = m reflect res.func // Instance Mirror 

Вы можете получить метод apply из членов его типа:

val apply = newTermName("apply") 
val applySymbol = im.symbol.typeSignature member apply 

И так как мы знаем, что это метод, сделайте его символом метода:

val applyMethod = applySymbol.asMethod 

Это параметр RS можно найти через paramss, и мы знаем, что есть только один параметр в одном списке параметров, так что мы можем получить первый параметр первого списка параметров:

val param = applyMethod.paramss(0)(0) 

Тогда то, что вы просите является:

val name = param.name.decoded // if you want "+" instead of "$plus", for example 
val type = param.typeSignature 

Вполне возможно, что вы думаете, что это неправильный ответ, потому что вы получили x$1 вместо name1, но то, что передается в конструктор не названная функцияtestFunc, но, вместо этого, ано nymous, представляющий этот метод, созданный с помощью процесса, называемого eta expansion. Вы не можете узнать имя параметра метода, потому что вы не можете пройти метод.

Если это то, что вам нужно, я предлагаю вам вместо этого использовать макрос. С помощью макроса вы сможете точно увидеть, что передается во время компиляции и получить от него имя.

Смежные вопросы