我正在编写REST Web服务的包装器,我想要强类型的Scala API.
以下是我到目前为止所做的事情:
def getMentions(count: Option[Int] = None,
sinceID: Option[TweetID] = None,
maxID: Option[TweetID] = None,
trimUser: Option[Boolean] = None,
contributorDetails: Option[Boolean] = None,
includeEntities: Option[Boolean] = None) : List[Tweet] = {
val parameters = Map("count" -> count,
"since_id" -> sinceID,
"max_id" -> maxID,
"trim_user" -> trimUser,
"contributor_details" -> contributorDetails,
"include_entities" -> includeEntities)
/*
* Convert parameters, which is a Map[String,Any] to a Map[String,String]
* (Removing Nones) and pass it to an object in charge of generating the request.
*/
...
}
Run Code Online (Sandbox Code Playgroud)
这种方法很有效,但它需要我手动生成parameters地图.如果我能够访问代表参数及其值的Map,那么我所做的将更加清晰.
Tra*_*own 12
你可以通过运行时反射来做到这一点,我相信你会得到答案,告诉你如何,如果你想要,但这实际上是Scala 2.10的宏的一个简洁的用例,所以这里.首先假设我们有一个名为的文件ParamMapMaker.scala:
object ParamMapMaker {
def paramMap: Map[String, Any] = macro paramMapImpl
def paramMapImpl(c: scala.reflect.macros.Context) = {
import c.universe._
val params = c.enclosingMethod match {
case DefDef(_, _, _, ps :: Nil, _, _) =>
ps.map(p =>
reify((
c.Expr[String](Literal(Constant(p.name.decoded))).splice,
c.Expr[Any](Ident(p.symbol)).splice
)).tree
)
case _ => c.abort(c.enclosingPosition, "Can't call paramMap here!")
}
c.Expr[Map[String, Any]](Apply(Select(Ident("Map"), "apply"), params))
}
}
Run Code Online (Sandbox Code Playgroud)
我会留下蛇套管地图键作为读者的(简单)练习.
我们还有一个测试文件(命名Test.scala):
object Test extends App {
def foo(hello: String, answer: Int) = ParamMapMaker.paramMap
println(foo("world", 42))
}
Run Code Online (Sandbox Code Playgroud)
现在我们编译这两个:
scalac -language:experimental.macros ParamMapMaker.scala
scalac Test.scala
Run Code Online (Sandbox Code Playgroud)
当我们运行时,Test我们将得到以下内容:
Map(hello -> world, answer -> 42)
Run Code Online (Sandbox Code Playgroud)
关于这一点的好处是没有运行时反射的开销.如果我们使用编译测试文件-Ymacro-debug-verbose,我们会看到foo在编译时为生成器生成了以下代码(实际上):
Map.apply[String, Any](
scala.Tuple2.apply[String, String]("hello", hello),
scala.Tuple2.apply[String, Int]("answer", answer)
)
Run Code Online (Sandbox Code Playgroud)
正如我们所期望的那样.
| 归档时间: |
|
| 查看次数: |
566 次 |
| 最近记录: |