5

扩展这篇博文,我试图使用一个类别来创建一个简单的 DSL 以用于javax.measure(JSR-275)类(类似于时间间隔的 TimeCategory)

但是,我不想为每个可能的可用方法(getMeter、getMilliMeter、getKelvin、getSecond 等)添加样板代码。我认为覆盖该getProperty(String)方法会起作用,但是,在直接访问该属性时,似乎getProperty没有使用该类别中定义的方法。

下面是一些简化的代码来演示: import javax.measure.quantity.Length; 导入 javax.measure.unit.Unit;导入 javax.measure.Measure;

@Category(Number)
class LengthCategory {      
    public Measure<BigDecimal, Length> getProperty(String unit){
        return Measure.valueOf(this,Unit.valueOf(unit));
    }
}

use(LengthCategory){
    println 3.getProperty("m")  // this works
    println 3.m                 // this reports a non-exisiting property
    prinlln 3.'m'               // as does this
}

假设其他动态添加属性到运行时对象的方法(例如Expando,子类化GroovyInterceptible、混合和其他元类操作)是不可行的,我真的宁愿不必为每个可能的单位和 SI 前缀组合手动编写 getter。显然还有其他方法可以创建用于测量的 DSL,但我仍然想了解为什么这种方法不起作用。

有人可以解释为什么该getProperty类别的方法不会覆盖.propertyName使用情况吗?我显然错过了在运行时使用元类解析属性名称的重要内容。

4

3 回答 3

4

我不知道为什么getProperty不适用于类别。但是您可以get在它们上定义一个基本相同的方法(我认为)。这有效:

@Category(Number)
class LengthCategory {      
    def get(String unit) {
        "$this $unit"
    }
}

use (LengthCategory) {
    println 3.m   // 3 m
    println 3.'m' // 3 m
}
于 2013-02-26T19:17:02.467 回答
0

据我所知,您实际上不能使用 Category 来扩展具有完整(即可读和可写)属性的整数——只能使用方法。

您可以通过使用属性的方法版本来使用只读属性扩展 Integer。您甚至可以通过包含 set 方法使其可写。但是,似乎没有办法将传入的值存储在静态变量中,这最终会影响所有整数。

例子:

$ cat catprop
#!/usr/local/bin/groovy

@Category(Integer)
class CatInteger {
  private static String str = "default"
  public static String setN(Integer i, String _str) { str = _str }
  public static String getN(Integer i) { return str }
}

use (CatInteger) {
  3.n = "333a"
  println "3.n is " + 3.n

  3.n = "333b"
  println "3.n is " + 3.n

  4.n = "444"
  println "4.n is " + 4.n
  println "3.n is " + 3.n
}
$ catprop
3.n is 333a
3.n is 333b
4.n is 444
3.n is 444
$

请注意,在最后一行 3.n 中返回“444”,因为存储的字段是静态的。我想人们可以使用私有 HashMap 并为每个访问的 Integer 存储一个值,但这太难看了。

另一种可能性是使用 MetaClass 接口的 getProperty() 和 setProperty()。但是,我还没有研究过,所以我不知道它是否会起作用(只是一个想法)。

于 2016-10-14T17:37:33.960 回答
0

不错的答案,但不确定,既然JSR-363是最终版本,您是否仍想使用 JSR-275?;-)

于 2016-10-28T12:23:18.470 回答