在 Scala 中,有什么方法可以获取参数的方法名称和类吗?

发布于 2024-11-04 14:10:04 字数 1194 浏览 1 评论 0原文

在我的工作中,我们使用 Hibernate、Spring 和 JSF 等典型的重型企业堆栈来处理我们的应用程序,但在学习 Scala 后,我想尝试在更小的 Scala 堆栈(Squeryl、Scalatra、Scala)中复制我们的大部分功能。 )看看我是否可以减少代码并提高性能(现在是我们的致命弱点)。

我的做事方式通常会受到之前堆栈的影响,因此我愿意接受有关更接近 Scala 范例的做事方式的建议。不过,我根据 Java 代码库中以前的范例选择了我所做的一些工作,以便其他团队成员能够更容易地接受我正在做的工作。但我的问题是:

我们有一个像这样的域类:

class Person(var firstName: String, var lastName: String)

在一个玉模板中,我进行如下调用:

.section
  - view(fields)

支持类有一个字段列表,如下所示:

class PersonBean(val person: Person) {
  val fields: Fields = Fields(person,
    List(
      Text(person.firstName),
      Text(person.lastName)
    ))
}

Fields 有一个基础对象(人)和一个 Field 对象列表。它的模板打印所有字段模板。 Text 扩展了 Field,其 Jade 模板应该打印:

<label for="person:firstName">#{label}</label>: <input type="text" id="person:firstName" value="#{value}" /> 

现在 #{value} 只是对 person.firstName 的调用。但是,为了找出标签,我引用了 ResourceBundle 并且需要生成一个字符串键。我正在考虑使用这样的命名约定:

person.firstName.field=First Name

所以问题就变成了,我如何在 Text 类(或父 Field 类)中发现传入的参数是什么?有没有办法可以传入 person.firstName 并发现它正在调用 Person 类上的firstName?最后,我的想法完全错误吗?

At my work we use a typical heavy enterprise stack of Hibernate, Spring, and JSF to handle our application, but after learning Scala I've wanted to try to replicate much of our functionality within a more minimal Scala stack (Squeryl, Scalatra, Scalate) to see if I can decrease code and improve performance (an Achilles heal for us right now).

Often my way of doing things is influenced by our previous stack, so I'm open to advice on a way of doing things that are closer to Scala paradigms. However, I've chosen some of what I do based on previous paradigms we have in the Java code base so that other team members will hopefully be more receptive to the work I'm doing. But here is my question:

We have a domain class like so:

class Person(var firstName: String, var lastName: String)

Within a jade template I make a call like:

.section
  - view(fields)

The backing class has a list of fields like so:

class PersonBean(val person: Person) {
  val fields: Fields = Fields(person,
    List(
      Text(person.firstName),
      Text(person.lastName)
    ))
}

Fields has a base object (person) and a list of Field objects. Its template prints all its fields templates. Text extends Field and its Jade template is supposed to print:

<label for="person:firstName">#{label}</label>: <input type="text" id="person:firstName" value="#{value}" /> 

Now the #{value} is simply a call to person.firstName. However, to find out the label I reference a ResourceBundle and need to produce a string key. I was thinking of using a naming convention like:

person.firstName.field=First Name

So the problem then becomes, how can I within the Text class (or parent Field class) discover what the parameter being passed in is? Is there a way I can pass in person.firstName and find that it is calling firstName on class Person? And finally, am I going about this completely wrong?

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

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

发布评论

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

评论(4

陪我终i 2024-11-11 14:10:04

如果您想尝试一下狂野的一面,Scala 中有一个(隐藏的)API,可以让您在运行时获取一段代码的语法树。

这个咒语是这样的:

scala.reflect.Code.lift(f).tree

这应该包含您需要的所有信息,然后是一些信息,但是您将需要完成解释输出的工作。

您还可以在这里阅读有关该主题的更多信息:我可以获得 AST来自实时 scala 代码?

不过请注意...它被正确地分类为实验性的,这样做需要您自担风险!

If you want to take a walk on the wild side, there's a (hidden) API in Scala that allows you to grab the syntax tree for a thunk of code - at runtime.

This incantation goes something like:

scala.reflect.Code.lift(f).tree

This should contain all the information you need, and then some, but you'll have your work cut out interpreting the output.

You can also read a bit more on the subject here: Can I get AST from live scala code?

Be warned though... It's rightly classified as experimental, do this at your own risk!

一向肩并 2024-11-11 14:10:04

您永远无法在 Java 中任何地方执行此操作,因此我不完全清楚您是如何遵循您习惯的习惯用法的。这是不可能的,明显的原因是 Java 是按值传递的。因此:

public void foo(String s) { ... }

参数 s 没有任何意义。 person.firstName 只是因为您调用了 foo ,如下所示:

foo(person.firstName);

因为 person.firstNames 是完全独立的引用

You can never do this anywhere from within Java, so I'm not wholly clear as to how you are just following the idiom you are used to. The obvious reason that this is not possible is that Java is pass-by-value. So in:

public void foo(String s) { ... }

There is no sense that the parameter s is anything other than what it is. It is not person.firstName just because you called foo like:

foo(person.firstName);

Because person.firstName and s are completely separate references!

浅忆 2024-11-11 14:10:04

您可以做的是将字段(例如名字)替换为具有名称属性的实际对象。

我在最近的一篇博客文章中做了类似的事情:http://blog.schauderhaft.de/2011/05/01/binding-scala-objects-to-swing-components/

该属性还没有 name 属性,但它是一个完整的对象,但仍然像字段一样易于使用。

What you could do is replacing the fields (e.g. firstname) with actual objects, which have a name attribute.

I did something similiar in a recent blog post:http://blog.schauderhaft.de/2011/05/01/binding-scala-objects-to-swing-components/

The property doesn't have a name property (yet), but it is a full object but is still just as easy to use as a field.

烟─花易冷 2024-11-11 14:10:04

如果以下内容完全是废话,我不会感到非常惊讶:

  • 将传入的参数类型设置为 A 类型,而不是 A 而是 Context[A]
  • 创建一个隐式函数,将任何 A 转换为 Context[A] ,并在执行此操作时捕获按名称调用参数中的参数值,
  • 然后使用反射检查传入的按名称调用参数

为此,你需要非常具体的知识来了解如何将东西变成按名称调用的函数;以及如何提取您想要的信息(如果存在的话)。

I would not be very surprised if the following is complete nonsense:

  • Make the parameter type of type A that gets passed in not A but Context[A]
  • create an implicit that turns any A into a Context[A] and while doing so captures the value of the parameter in a call-by-name parameter
  • then use reflection to inspect the call-by-name parameter that gets passed in

For this to work, you'd need very specific knowledge of how stuff gets turned into call-by-name functions; and how to extract the information you want (if it's present at all).

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