在特征(或类)方法之间遍历

发布于 2024-10-18 22:39:44 字数 400 浏览 1 评论 0原文

trait t{
  val y = "z"
  def t1(x:String):String=x+"a"+y
  def t2(x:String):String= x+"b"+y
  def t3(x:String):String= x+"c"+y
}
class c extends t {
  val funcSet = Set(t1 _,t2 _,t3 _)
  def multiBitamin(input:String) = for(f <- funcSet) yield f(input)
}

像 funcSet 这样的 Set

val funcSet = Set("t1","t2","t3") 

我想在 t1,t2,t3 之间遍历,而不接受

trait t{
  val y = "z"
  def t1(x:String):String=x+"a"+y
  def t2(x:String):String= x+"b"+y
  def t3(x:String):String= x+"c"+y
}
class c extends t {
  val funcSet = Set(t1 _,t2 _,t3 _)
  def multiBitamin(input:String) = for(f <- funcSet) yield f(input)
}

I want traverse between t1,t2,t3 without having a Set like funcSet

val funcSet = Set("t1","t2","t3") 

accepted

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我只土不豪 2024-10-25 22:39:44

实现这一点的方法仍然是使用反射,尽管这可以为您提供一些额外的方法(如下面的 toString ):

scala> trait t{
     |   val y = "z"
     |   def t1(x:String):String=x+"a"+y
     |   def t2(x:String):String= x+"b"+y
     |   def t3(x:String):String= x+"c"+y
     | }
defined trait t

scala> val inst = new t{}

scala> inst.getClass.getMethods.filter(_.getName.startsWith("t")) map { m => (s: String) => m.invoke(inst, s) }

然后使用结果来遍历函数。当然,您可以比这更聪明,根据参数的数量及其类型过滤方法,并将包装器存储在底层映射中以访问它们。

编辑:

如果您有要调用的方法的特定名称(例如 t1),您可以执行以下操作:

scala> val f = (s: String) => inst.getClass.getMethods.find(_.getName == "t1").get.invoke(inst, s)                  
f: (String) => java.lang.Object = <function1>

实现此目的的另一种方法是在方法名称已知的情况下在调用站点使用结构类型编译时:

scala> (inst: AnyRef).asInstanceOf[{def t1(s: String): String}].t1("Hello ")
res9: String = Hello az 

请注意,您不能像以前一样在此处使用字符串。这也在幕后使用了反射。

此外,Scala 中还添加了一个新的Dynamic 特征,其子类将允许使用在运行时获取的名称来调用方法。这将在未来的某些版本中提供。

The way to do this is still to use reflection, although this can give you some additional methods (like toString below):

scala> trait t{
     |   val y = "z"
     |   def t1(x:String):String=x+"a"+y
     |   def t2(x:String):String= x+"b"+y
     |   def t3(x:String):String= x+"c"+y
     | }
defined trait t

scala> val inst = new t{}

scala> inst.getClass.getMethods.filter(_.getName.startsWith("t")) map { m => (s: String) => m.invoke(inst, s) }

and then use the result to traverse the functions. Of course, you could be smarter than this, and filter the methods according to the number of parameters and their types, and store the wrappers in an underlying map to access them.

EDIT:

If you have a specific name of a method you wish to call (say t1), you can do:

scala> val f = (s: String) => inst.getClass.getMethods.find(_.getName == "t1").get.invoke(inst, s)                  
f: (String) => java.lang.Object = <function1>

Another way to accomplish this is to use structural types at the callsite if the method name is known at compile time:

scala> (inst: AnyRef).asInstanceOf[{def t1(s: String): String}].t1("Hello ")
res9: String = Hello az 

Note that you cannot use a string here, like before. This also uses reflection under the hood.

Also, a new Dynamic trait is being added to Scala, subclasses of which will allow calling a method using its name obtained at runtime. This will be available in some of the future releases.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文