【问题标题】:What's the best practice to work with ENUM in Intersystems Caché?在 Intersystems Caché 中使用 ENUM 的最佳实践是什么?
【发布时间】:2015-12-08 09:31:47
【问题描述】:

Caché 本身并没有实现 Java 等 ENUM,当您需要在 Java 中实现类似以下示例的解决方案时,但在 Caché 中,最佳实践是什么?

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7);

    private final double mass;   // in kilograms
    private final double radius; // in meters
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    } 
    private double mass() { return mass; }
    private double radius() { return radius; }
}

final Planet mars = Planet.MARS;

访问代码只需Planet.MARS

【问题讨论】:

    标签: caching enums intersystems-cache intersystems


    【解决方案1】:

    我以前从来没有用缓存做过这样的事情,但我想你可以做这样的事情:(Ab)使用属性的动态调度。

    Class TST.Planet Extends %RegisteredObject  
    {
    
      Property Mass As %Library.Double;
      Property Radius As %Library.Double;
    
      /// Property dispatch method to catch references to 
      /// virtual properties.<br>
      /// This should not be called directly.<br>
      Method %DispatchGetProperty(pProperty As %String) [ Final, Internal ]
      {
            #Dim Planets As %Library.String // multidimensional
            s Planets("MERCURY")=3.303e+23_"\"_2.4397e6
            s Planets("VENUS")=4.869e+24_"\"_6.0518e6
            s Planets("EARTH")=5.976e+24_"\"_6.37814e6
            s Planets("MARS")=6.421e+23_"\"_3.3972e6
            s Planets("JUPITER")=1.9e+27_"\"_7.1492e7
            s Planets("SATURN")=5.688e+26_"\"_6.0268e7
            s Planets("URANUS")=8.686e+25_"\"_2.5559e7
            s Planets("NEPTUNE")=1.024e+26_"\"_2.4746e7
            if $DATA(Planets(pProperty)) {
              s result = ##class(TST.Planet).%New()
              s result.Mass=$PIECE(Planets(pProperty),"\",1)
               s result.Radius=$PIECE(Planets(pProperty),"\",2)
              q result
            }
          }
      }
    

    然后你必须像这样使用它:

    s x = ##Class(TST.Planet).%New()
    s x = x.MARS
    zw x
    
    EDIT: can also do s x =##Class(TST.Planet).%New().MARS
    

    得到这个结果:

    x=<OBJECT REFERENCE>[2@TST.Planet]
    +----------------- general information ---------------
    |      oref value: 2
    |      class name: TST.Planet
    | reference count: 2
    +----------------- attribute values ------------------
    |               Mass = 642100000000000000000000
    |             Radius = 3397200
    

    【讨论】:

    • 嗨,这个想法是有效的,但我想要一个小细节的解决方案,我不想写“##Class(TST.Planet).%New().MARS”,你明白吗?现在,我正在测试使用宏来抽象为 $$$Planet(MARS)...但我还没有一个像样的解决方案。
    • 嘿,通过方法分派,您可能会将其缩短为 ##Class(TST.Planet).MARS()。但我不知道这是否足够。
    • 看DAiMor的回答,很有意思。
    【解决方案2】:

    可计算参数示例

    Class so.Enum Extends %RegisteredObject
    {
    
    Parameter MERCURY As COSEXPRESSION = "..%New(3.303e+23, 2.4397e6)";
    
    Parameter VENUS As COSEXPRESSION = "..%New(4.869e+24, 6.0518e6)";
    
    Parameter EARTH As COSEXPRESSION = "..%New(5.976e+24, 6.37814e6)";
    
    Parameter MARS As COSEXPRESSION = "..%New(6.421e+23, 3.3972e6)";
    
    Parameter JUPITER As COSEXPRESSION = "..%New(1.9e+27,   7.1492e7)";
    
    Parameter SATURN As COSEXPRESSION = "..%New(5.688e+26, 6.0268e7)";
    
    Parameter URANUS As COSEXPRESSION = "..%New(8.686e+25, 2.5559e7)";
    
    Parameter NEPTUNE As COSEXPRESSION = "..%New(1.024e+26, 2.4746e7)";
    
    Property Mass As %Double;
    
    Property Radius As %Double;
    
    Method %OnNew(mass, radius) As %Status
    {
        set ..Mass=mass
        set ..Radius=radius
        quit $$$OK
    }
    
    }
    

    而且,你可以这样使用它

    USER>w ##class(so.Enum).#MERCURY.Mass
    330300000000000000000000
    USER>w ##class(so.Enum).#MERCURY.Radius
    2439700
    USER>w ##class(so.Enum).#MERCURY.Radius
    2439700
    USER>w ##class(so.Enum).#EARTH.Radius
    6378140
    USER>w ##class(so.Enum).#EARTH
    1@so.Enum
    USER>w ##class(so.Enum).#MERCURY
    1@so.Enum
    

    您可以将其定义为宏

    #define MERCURY ##class(so.Enum).#MERCURY
    

    #define Planet(%planet) $parameter("so.Enum",$zcvt("%planet","U"))
    

    【讨论】:

      猜你喜欢
      • 2018-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-11
      • 1970-01-01
      • 2011-06-07
      相关资源
      最近更新 更多