斯卡拉设置功能参数由名使用字符串(Scala set function parameter by n

2019-10-18 14:43发布

是否有可能通过名使用字符串设定一个函数的参数。

例如:

给定:

def foo(a: String, b: String)

我可以动态调用此功能和地图状

Map(("a", "bla"), ("b", "blub"))

如果是这样,怎么样?

谢谢!

Answer 1:

应用args来反思地图的方法:

apm@mara:~/tmp$ scalam
Welcome to Scala version 2.11.0-M4 (OpenJDK 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val m = Map(("a", "bla"), ("b", "blub"))
m: scala.collection.immutable.Map[String,String] = Map(a -> bla, b -> blub)

scala> import reflect.runtime._
import reflect.runtime._

scala> import universe._
import universe._

scala> class Foo { def foo(a: String, b: String) = a + b }
defined class Foo

scala> val f = new Foo
f: Foo = Foo@2278e0e7

scala> typeOf[Foo].member(TermName("foo"))
res0: reflect.runtime.universe.Symbol = method foo

scala> .asMethod
res1: reflect.runtime.universe.MethodSymbol = method foo

scala> currentMirror reflect f
res2: reflect.runtime.universe.InstanceMirror = instance mirror for Foo@2278e0e7

scala> res2 reflectMethod res1
res3: reflect.runtime.universe.MethodMirror = method mirror for Foo.foo(a: String, b: String): java.lang.String (bound to Foo@2278e0e7)

scala> res1.paramss.flatten
res5: List[reflect.runtime.universe.Symbol] = List(value a, value b)

scala> .map(s => m(s.name.decoded))
res7: List[String] = List(bla, blub)      

scala> res3.apply(res7: _*)
res8: Any = blablub

请注意,你要扁平化参数列表, paramss.flatten 。 也就是说PARAMS它可以映射到您ARGS平凡的有序列表。

聪明的命名约定paramss是为了传达多重嵌套; 就个人而言,我念它,就好像是拼写paramses英文。

但现在,我看到它阐明了,我可以用它来与埃及法老韵。



Answer 2:

OK,这里去与反思。 这不是每个参数名通过精确地结合Map ,但你必须保持与参数值的序列顺序,因此第一个值将是a ,第二个为b等我会说这是足够接近

一切都取自这里 ,其实它是在镜子的优秀资源。

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

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> class Bar { def foo(a : String, b : String) { println(a + ", " + b + "!")
}}
defined class Bar

scala> val instanceMirror = ru.runtimeMirror(getClass.getClassLoader).reflect(new Bar)
instanceMirror: reflect.runtime.universe.InstanceMirror = instance mirror for Bar@47f3b292

scala> val fooMethod = typeOf[Bar].declaration(newTermName("foo")).asMethod
fooMethod: reflect.runtime.universe.MethodSymbol = method foo

scala> val method = instanceMirror.reflectMethod(fooMethod)
method: reflect.runtime.universe.MethodMirror = method mirror for Bar.foo(a: String, b: String): scala.Unit (bound to Bar@47f3b292)

scala> val args = Seq("Hey", "you")
args: Seq[String] = List(Hey, you)

scala> method(args: _*)
Hey, you!
res0: Any = ()

如果该方法返回任何东西,没有问题,但返回类型将是Any (文档) :

scala> class Bar { def foo(a : String, b : String) = a + b }
defined class Bar

scala> val instanceMirror = ru.runtimeMirror(getClass.getClassLoader).reflect(ne
w Bar)
instanceMirror: reflect.runtime.universe.InstanceMirror = instance mirror for Bar@642e0260

scala> val fooMethod = typeOf[Bar].declaration(newTermName("foo")).asMethod
fooMethod: reflect.runtime.universe.MethodSymbol = method foo

scala> val method = instanceMirror.reflectMethod(fooMethod)
method: reflect.runtime.universe.MethodMirror = method mirror for Bar.foo(a: String, b: String): java.lang.String (bound to Bar@642e0260)

scala> val args = Seq("Testing", "concatenation")
args: Seq[String] = List(Testing, concatenation)

scala> method(args: _*)
res5: Any = Testingconcatenation


Answer 3:

没有反思,您的设置:

val valmap = Map (("a", "bla"), ("b", "blub"))
def foo (a: String, b: String) = a + "-baz-" + b

一个函数,它负责名称映射:

def fmap (m: Map[String, String]) : String = (m.get("a"), m.get ("b")) match {
     case (Some(s), Some (t)) => foo (s, t) 
     case _ => "didn't match" 
}

Invokation:

fmap (valmap) 
// res0: String = bla-baz-blub

一个更好的名字比FMAP,这可能与flatmap混淆,可能是有用的。 请注意,地图并不保证包含某些键,所以我们没有得到字符串,但字符串的选项返回。

该名称不会在编译时保证匹配和调用该函数与S和T到底。 但有时你可能需要这样的功能,并具有内在证据,即“A”和“B”是在地图上。 当然,你可以调用每一个方法,预计2串那样任意名称,最简单的一个与B,A来代替A,B:

     // ... 
     case (Some(s), Some (t)) => foo (t, s) 
     // ...

与阵列的类似的方法:

val arr: Array[String] = (Seq.fill ('c')("not initialized")).toArray
arr('a')="bla" 
arr('b')="blub" 
def fmap (ar: Array[String]) : String = foo (ar('a'), ar('b')) 
fmap (arr) 

Seq.fill(“C”)......从“\ 0”到“B”填充阵列,所以你得到相当稀疏阵,只处理2倍的值。 如果你将填补它,直到“Z”,你可以动态调用该函数:

def fmap (ar: Array[String], c1: Char, c2: Char) : String = foo (ar(c1), ar(c2)) 

fmap (arr, 'a', 'b') 
fmap (arr, 'b', 'a') 
fmap (arr, 'a', 'a') 
fmap (arr, 'i', 't') 

等等。



文章来源: Scala set function parameter by name with a string
标签: scala