在 switch-case 语句中使用 Enum 的序数值

发布于 11-25 23:59 字数 521 浏览 3 评论 0原文

对于我的项目,我使用枚举,并且需要实现 switch-case 语句,其中检查特定枚举的值的序数,如下所示:

        switch ( variable )
        {
        case MyEnum.A.ordinal():
            return true;
        case MyEnum.B.ordinal():
            return true;
        default:
            return false;
        }

注意:返回值只是一个示例。

不幸的是,Eclipse(我使用的是 1.6 JDK)给出了我的编译错误“case 表达式必须是常量表达式”。我应该做什么?除了静态查找表之外还有其他方法吗,如下所述: 从枚举序数转换为枚举类型 ?

For my project I am using enums, and I need to implement the switch-case statement, where ordinal numbers of values of the specific Enum are checked, like this way:

        switch ( variable )
        {
        case MyEnum.A.ordinal():
            return true;
        case MyEnum.B.ordinal():
            return true;
        default:
            return false;
        }

Note: return values are only an example.

Unfortunately, Eclipse (I'm using 1.6 JDK) gives my compilation error "case
expressions must be constant expressions". What I should do? Is there any other method than static lookup table, described here: Convert from enum ordinal to enum type ?

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

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

发布评论

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

评论(7

微暖i2024-12-02 23:59:46

这是因为编译器会看到差异。例如这个枚举代码,我们可以看到:

public enum TrafficLight {RED, YELLOW, GREEN}

TrafficLight trafficLights = ...
switch (trafficLights) {
  case RED: {/* do stuff */}
  case YELLOW: {/* do stuff */}
  case GREEN: {/* do stuff */}
}

但是编译器看到:

switch (trafficLights.ordinal()) {
      case 0: {/* do stuff */}
      case 1: {/* do stuff */}
      case 2: {/* do stuff */}
    }

这就是为什么当交通灯为 NULL 时它会抛出 NPE,并且您也不知道为什么它在 ordinal() 函数中抛出 NPE,即使我们没有调用该方法。

解决方案是在 ENUM 到达 switch-case 之前检查 NULL。

if (trafficLights != null) {
  switch (trafficLights) {
  case RED: {/* do stuff */}
  case YELLOW: {/* do stuff */}
  case GREEN: {/* do stuff */}
  }
} 

It is because the compiler sees differences. For example this enum code, we can see:

public enum TrafficLight {RED, YELLOW, GREEN}

TrafficLight trafficLights = ...
switch (trafficLights) {
  case RED: {/* do stuff */}
  case YELLOW: {/* do stuff */}
  case GREEN: {/* do stuff */}
}

BUT the compiler see:

switch (trafficLights.ordinal()) {
      case 0: {/* do stuff */}
      case 1: {/* do stuff */}
      case 2: {/* do stuff */}
    }

That's why it throws NPE when trafficLights are NULL and you also don't know why it throws NPE in the ordinal() function even though we didn't call that method.

SOLUTION is checking NULL the ENUM before it reaches to the switch-case.

if (trafficLights != null) {
  switch (trafficLights) {
  case RED: {/* do stuff */}
  case YELLOW: {/* do stuff */}
  case GREEN: {/* do stuff */}
  }
} 
债姬2024-12-02 23:59:45

假设您在某处以某种方式有一个序列化序数,这就是完成的方法。不过,持久化枚举的通常方法是通过其名称,而不是序号。另外,在正常情况下你不应该使用序数,除非尝试实现类似 EnumMap/Set 的东西。当然,枚举可以只是 C 类似内容的一个端口,并且处理不可避免的 int,需要转换为 Enum 对象。

只需使用 Enum.values() 即可获取按 ordinal() 排序的数组,因为每次都会克隆该数组,因此保留一个引用即可。

enum E{
 A, B, C...   
}

final static E[] vals = E.values();//copy the values(), calling values() clones the array
boolean f(int variable){
  switch(vals[variable]){
  case A:
...
  case B:
...
//break;
  default:
...
   }
}

只是注意到你只需要 true 和 false,这是一种 Set 类型的行为。如果您足够勇敢(并且枚举常量不超过 64 个),您可以使用 java.util.EnumSet 或简单的 long。例如:

private static <E extends Enum> long ord(E e){
  return 1L<<e.ordinal();
}

static final long positiveSet = ord(E.A)+ord(E.B);
boolean f(int ordinal){
  return 0!=(positiveSet&(1L<<ordinal));
}

This is how is done, provided you have a serialized ordinal somehow, somewhere. Usual way to persist an enum is by its name, not ordinal, though. Also you should not use ordinal in normal circumstances unless trying to implement something like EnumMap/Set. Of course, the enum can be just a port from C alike stuff and dealing with the inevitable int, needs a transform to the Enum object.

Just use Enum.values() to obtain an array ordered by ordinal(), since the array is cloned each time, keeping a ref towards is ok.

enum E{
 A, B, C...   
}

final static E[] vals = E.values();//copy the values(), calling values() clones the array
boolean f(int variable){
  switch(vals[variable]){
  case A:
...
  case B:
...
//break;
  default:
...
   }
}

Just noticed you need only true and false, that's a Set type of behavior. You can use java.util.EnumSet or a simple long, if feeling brave (and not having more than 64 enum constants). for example:

private static <E extends Enum> long ord(E e){
  return 1L<<e.ordinal();
}

static final long positiveSet = ord(E.A)+ord(E.B);
boolean f(int ordinal){
  return 0!=(positiveSet&(1L<<ordinal));
}
溺渁∝2024-12-02 23:59:45

首先,你不应该太依赖序数。如果可能的话,将变量设为 String (并使用 Enum.valueOf(string) 转换为 enum 或最多将其设为 enum< /code>。

如果你确实不能,那么使用enum.values()[ordinal]。然后在开关中使用枚举。

First of all, you should not rely on the ordinal that much. If possible make your variable a String (and transform to enum using Enum.valueOf(string) or at best make it enum.

If you really can't, then use enum.values()[ordinal].Then use the enum in the switch.

冷清清2024-12-02 23:59:45

答案针对 @Riaan 对常量与方法枚举和性能原因的评论,它并没有直接回答OP问题,所以我想它可以被认为是噪音。
然而,我相信了解内部运作方式是很重要的。

我从他的示例中获取了基准并对其进行了改进,以消除占用 90% 以上执行时间的垃圾收集和字符串创建。添加了预热阶段以确保热点实际编译方法。

还有更多,基准测试是有效的调用站点测试。对于 1、2、少数更多和更多更多,调用站点的优化有很大不同。调用点是对抽象(或只是重写)方法的调用。

下面是使用 6 个枚举常量的测试:

package t1;

public class ZEnums {

    public enum MyEnum {
  A { boolean getBooleanValue(){ return true; }},
  B { boolean getBooleanValue(){ return true; }},
  C { boolean getBooleanValue(){ return false; }},
  D { boolean getBooleanValue(){ return false; }},
  E { boolean getBooleanValue(){ return false; }},
  F { boolean getBooleanValue(){ return false; }}, 

  ;
  abstract boolean getBooleanValue();
  }

  public enum MyEnumAlt {
    A (true), 
    B (true),
    C (false),
    D (false),
    E (false),
    F (false),
    ;
    private final boolean isTrue;
    MyEnumAlt( boolean isTrue){ this.isTrue = isTrue; }
    boolean getBooleanValue(){ return isTrue; };
  }

  public static void main(String[] args) {
    log("Warming up...");
    //10k iterations won't do since not all paths for MyEnum are invoked 10k (default) times to warrant compilations 
    long warmum = testEnum(100000 )+ testAlt(100000)+testEnum(100000 )+ testAlt(100000);
    log("Warm up: %d", warmum);     
    //no info from +XX:+PrintCompilation below this one, or the test is invalid
    testMain();

    }
    public static void testMain() {
        int iterations = (int)4e7;

        log("Testing %d iterations%n", iterations);
        log("====");

        log("Testing with Overridden method...");       
    System.gc();
    {
    long start = System.currentTimeMillis();
    long len = 0;
    len = testEnum(iterations);
    long time = System.currentTimeMillis()-start;
    log("Overridden method version took %dms, length: %d ", time, len);
    }
////////////
    System.gc();
    {
    log("Testing with Constant in c-tor... ");
    long start = System.currentTimeMillis();
    long len = testAlt(iterations);

    long time = System.currentTimeMillis()-start;
    log("Constant in c-tor version took %dms, length: %d ", time, len);
    }
    }
    private static long testEnum(int iterations) {
        long len = 0;
        for(int i=0; i<iterations; i++){
        MyEnum tmpEnum = MyEnum.A;
        if(i%3==0){ tmpEnum = MyEnum.A;        
        }else if(i%4==0){ tmpEnum = MyEnum.B;
        }else if(i%5==0){ tmpEnum = MyEnum.C;
        }else if(i%6==0){ tmpEnum = MyEnum.D;
        }else if(i%6==0){ tmpEnum = MyEnum.E;
        }else{ tmpEnum = MyEnum.F; 
        }
        String tmp = tmpEnum.getBooleanValue()?"XXX":"ABCDE";
        len+=tmp.length();
    }
        return len;
    }
    private static long testAlt(int iterations) {
        long len =0;
        for(int i=0; i<iterations; i++){
        MyEnumAlt tmpEnum = MyEnumAlt.A;
        if(i%3==0){ tmpEnum = MyEnumAlt.A;
        }else if(i%4==0){ tmpEnum = MyEnumAlt.B;
        }else if(i%5==0){ tmpEnum = MyEnumAlt.C;
        }else if(i%6==0){ tmpEnum = MyEnumAlt.D;
        }else if(i%6==0){ tmpEnum = MyEnumAlt.E;
        }else{ tmpEnum = MyEnumAlt.F; 
        }
        String tmp = tmpEnum.getBooleanValue()?"XXX":"ABCDE";
        len+=tmp.length();
    }
        return len;
    }
    static void log(String msg, Object... params){ 
        String s = params.length>0?String.format(msg, params):msg;
        System.out.printf("%tH:%<tM:%<tS.%<tL %s%n", new Long(System.currentTimeMillis()), s);
    }
}
21:08:46.685 Warming up...
    148   1%      t1.ZEnums::testEnum @ 7 (125 bytes)
    150   1       t1.ZEnums$MyEnum$6::getBooleanValue (2 bytes)
    152   2       t1.ZEnums$MyEnum$1::getBooleanValue (2 bytes)
    154   3       t1.ZEnums$MyEnum$2::getBooleanValue (2 bytes)
    155   4       t1.ZEnums$MyEnum$3::getBooleanValue (2 bytes)
    158   2%      t1.ZEnums::testAlt @ 7 (125 bytes)
    162   5       t1.ZEnums::testEnum (125 bytes)
    164   6       t1.ZEnums::testAlt (125 bytes)
21:08:46.716 Warm up: 1600000
21:08:46.716 Testing 40000000 iterations

21:08:46.716 ====
21:08:46.716 Testing with Overridden method...
21:08:47.513 Overridden method version took 781ms, length: 160000000 
21:08:47.513 Testing with Constant in c-tor... 
21:08:48.138 Constant in c-tor version took 625ms, length: 160000000 

代码使用 -server -XX:+PrintCompilation 选项运行。
当然,差别并不大。但这不是有趣的问题。如果您使用 2 个枚举常量测试该版本,结果可能会显着不同。对于 2 个调用站点,编译器通过内联相关方法来生成代码。在上面的测试中,这将删除对 booleanValue 的整个调用,甚至可以在 O(1) 中执行测试。

然而,最有趣的部分是,当编译器开始使用内联缓存时,枚举常量从 2 个变为 3 个,然后是常量,哇哦,一切都发生了变化。


The bottom line is: proper benchmark is truly hard and involves some knowledge how the JIT compiles, when the GC might be an issue (either remove it or embrace it) and so on.

Links:

The answer targets @Riaan comment on constant vs method enums and performance reasons and it doesn't directly answers the OP question, so it can be considered noise I suppose.
However, I believe it's an important matter to understand how the inner workings.

I took the benchmark off his example and improved it to remove the garbage collection and string creation that takes over 90% of the execution time. Added warm up phase to ensure hotspot actually compiles the methods.

There is some more, the benchmark is effectively callsite test. The optimization for callsites are quite different for 1, for 2 for few more and for more-more. A callsite is an invocation of abstract (or just overridden) method.

Below is the test with 6 enums constants:

package t1;

public class ZEnums {

    public enum MyEnum {
  A { boolean getBooleanValue(){ return true; }},
  B { boolean getBooleanValue(){ return true; }},
  C { boolean getBooleanValue(){ return false; }},
  D { boolean getBooleanValue(){ return false; }},
  E { boolean getBooleanValue(){ return false; }},
  F { boolean getBooleanValue(){ return false; }}, 

  ;
  abstract boolean getBooleanValue();
  }

  public enum MyEnumAlt {
    A (true), 
    B (true),
    C (false),
    D (false),
    E (false),
    F (false),
    ;
    private final boolean isTrue;
    MyEnumAlt( boolean isTrue){ this.isTrue = isTrue; }
    boolean getBooleanValue(){ return isTrue; };
  }

  public static void main(String[] args) {
    log("Warming up...");
    //10k iterations won't do since not all paths for MyEnum are invoked 10k (default) times to warrant compilations 
    long warmum = testEnum(100000 )+ testAlt(100000)+testEnum(100000 )+ testAlt(100000);
    log("Warm up: %d", warmum);     
    //no info from +XX:+PrintCompilation below this one, or the test is invalid
    testMain();

    }
    public static void testMain() {
        int iterations = (int)4e7;

        log("Testing %d iterations%n", iterations);
        log("====");

        log("Testing with Overridden method...");       
    System.gc();
    {
    long start = System.currentTimeMillis();
    long len = 0;
    len = testEnum(iterations);
    long time = System.currentTimeMillis()-start;
    log("Overridden method version took %dms, length: %d ", time, len);
    }
////////////
    System.gc();
    {
    log("Testing with Constant in c-tor... ");
    long start = System.currentTimeMillis();
    long len = testAlt(iterations);

    long time = System.currentTimeMillis()-start;
    log("Constant in c-tor version took %dms, length: %d ", time, len);
    }
    }
    private static long testEnum(int iterations) {
        long len = 0;
        for(int i=0; i<iterations; i++){
        MyEnum tmpEnum = MyEnum.A;
        if(i%3==0){ tmpEnum = MyEnum.A;        
        }else if(i%4==0){ tmpEnum = MyEnum.B;
        }else if(i%5==0){ tmpEnum = MyEnum.C;
        }else if(i%6==0){ tmpEnum = MyEnum.D;
        }else if(i%6==0){ tmpEnum = MyEnum.E;
        }else{ tmpEnum = MyEnum.F; 
        }
        String tmp = tmpEnum.getBooleanValue()?"XXX":"ABCDE";
        len+=tmp.length();
    }
        return len;
    }
    private static long testAlt(int iterations) {
        long len =0;
        for(int i=0; i<iterations; i++){
        MyEnumAlt tmpEnum = MyEnumAlt.A;
        if(i%3==0){ tmpEnum = MyEnumAlt.A;
        }else if(i%4==0){ tmpEnum = MyEnumAlt.B;
        }else if(i%5==0){ tmpEnum = MyEnumAlt.C;
        }else if(i%6==0){ tmpEnum = MyEnumAlt.D;
        }else if(i%6==0){ tmpEnum = MyEnumAlt.E;
        }else{ tmpEnum = MyEnumAlt.F; 
        }
        String tmp = tmpEnum.getBooleanValue()?"XXX":"ABCDE";
        len+=tmp.length();
    }
        return len;
    }
    static void log(String msg, Object... params){ 
        String s = params.length>0?String.format(msg, params):msg;
        System.out.printf("%tH:%<tM:%<tS.%<tL %s%n", new Long(System.currentTimeMillis()), s);
    }
}
21:08:46.685 Warming up...
    148   1%      t1.ZEnums::testEnum @ 7 (125 bytes)
    150   1       t1.ZEnums$MyEnum$6::getBooleanValue (2 bytes)
    152   2       t1.ZEnums$MyEnum$1::getBooleanValue (2 bytes)
    154   3       t1.ZEnums$MyEnum$2::getBooleanValue (2 bytes)
    155   4       t1.ZEnums$MyEnum$3::getBooleanValue (2 bytes)
    158   2%      t1.ZEnums::testAlt @ 7 (125 bytes)
    162   5       t1.ZEnums::testEnum (125 bytes)
    164   6       t1.ZEnums::testAlt (125 bytes)
21:08:46.716 Warm up: 1600000
21:08:46.716 Testing 40000000 iterations

21:08:46.716 ====
21:08:46.716 Testing with Overridden method...
21:08:47.513 Overridden method version took 781ms, length: 160000000 
21:08:47.513 Testing with Constant in c-tor... 
21:08:48.138 Constant in c-tor version took 625ms, length: 160000000 

The code was run w/ -server -XX:+PrintCompilation options.
The difference ain't huge, of course. However that's not the interesting issue. If you test the version with 2 enum constants though, the result can be significantly different. For 2 call sites the compiler generates the code by inlinining the method in question. In the test above that would remove entire the call to booleanValue and can even make execute the test in O(1).

The funniest part however is going from 2 to 3 enum constants when the compiler starts using inline caches and then the constant, and WOW magic the everything changes.


The bottom line is: proper benchmark is truly hard and involves some knowledge how the JIT compiles, when the GC might be an issue (either remove it or embrace it) and so on.

Links:

长发绾君心2024-12-02 23:59:45

只需使用枚举常量:

MyEnum variable;
...
switch ( variable ) {
    case A:
        return true;
    case B:
        return true;
    default:
        return false;
}

假设类似:

public enum MyEnum {
    A, B
}

但要注意 NullPointerException (如果 variablenull

just use the enum constants:

MyEnum variable;
...
switch ( variable ) {
    case A:
        return true;
    case B:
        return true;
    default:
        return false;
}

assuming something like:

public enum MyEnum {
    A, B
}

but beware of NullPointerException (if variable is null)

纵情客2024-12-02 23:59:45

你所要求的可能是:
如果您需要枚举本身的方法中的 switch:

switch ( this )
        {
        case A:
            return true;
        case B:
            return true;
        default:
            return false;
        }

并且在不同的类中:

switch ( variable )  //Variable of type myEnum
        {
        case A:
            return true;
        case B:
            return true;
        default:
            return false;
        }

如果添加另一个枚举,很容易忘记更新 switch 语句,因此更好的选择是将这样的方法放在枚举本身中并使用特定于常量的方法实现:

public enum MyEnum
    A { boolean getBooleanValue(){ return true; },
    B { boolean getBooleanValue(){ return true; },
    C { boolean getBooleanValue(){ return false; };
    abstract boolean getBooleanValue();
}

这样,如果您添加新的枚举值,编译器将提醒您声明 getBooleanValue 方法,您只需在需要的地方使用 A.getBooleanValue();它。

正如评论中指出的,另一种选择是:

public enum MyEnumAlt {
    A (true), 
    B (true),
    C (false);
    private final boolean isTrue;
    MyEnumAlt( boolean isTrue){ this.isTrue = isTrue; }
    boolean getBooleanValue(){ return isTrue; };
}

这是一个偏好问题,会根据具体情况而有所不同。如果您只是为每个枚举返回一个值,则构造函数版本是合理的,但我发现它的可读性较差。通过测试可以看出,对这种性能更好的担忧是没有根据的:

public void testMain() {
        System.out.println("Testing with constructor: ");
        long start = System.currentTimeMillis();
        for(int i=0; i<1000*1000; i++){
            MyEnum tmpEnum = null;
            if(i%3==0){ tmpEnum = MyEnum.A;
            }else if(i%4==0){ tmpEnum = MyEnum.B;
            }else{ tmpEnum = MyEnum.C; }
            String tmp = Integer.toString(i)+" "+tmpEnum.getBooleanValue();
        }
        long time = System.currentTimeMillis()-start;
        System.out.println("Constructor version took "+time);

        System.out.println("Testing with Constant specific method implementation: ");
        long start2 = System.currentTimeMillis();
        for(int i=0; i<1000*1000; i++){
            MyEnumAlt tmpEnum2 = null;
            if(i%3==0){ tmpEnum2 = MyEnumAlt.A;
            }else if(i%4==0){ tmpEnum2 = MyEnumAlt.B;
            }else{ tmpEnum2 = MyEnumAlt.C; }
            String tmp2 = Integer.toString(i)+" "+tmpEnum2.getBooleanValue();
        }
        long time2 = System.currentTimeMillis()-start2;
        System.out.println("Constant specific method version took "+time2);
    }

What you are asking for is probably:
If you need the switch in a method in the enum itself:

switch ( this )
        {
        case A:
            return true;
        case B:
            return true;
        default:
            return false;
        }

And in a different class:

switch ( variable )  //Variable of type myEnum
        {
        case A:
            return true;
        case B:
            return true;
        default:
            return false;
        }

It's easy to forget to update the switch statements if you add another enum though, so a better bet would be to put methods like this in the enum itself and use constant-specific method implementations:

public enum MyEnum
    A { boolean getBooleanValue(){ return true; },
    B { boolean getBooleanValue(){ return true; },
    C { boolean getBooleanValue(){ return false; };
    abstract boolean getBooleanValue();
}

This way, if you ever add a new enum value, the compiler will remind you to declare the getBooleanValue method and you just use A.getBooleanValue(); wherever you need it.

As was pointed out in the comments, another option is this:

public enum MyEnumAlt {
    A (true), 
    B (true),
    C (false);
    private final boolean isTrue;
    MyEnumAlt( boolean isTrue){ this.isTrue = isTrue; }
    boolean getBooleanValue(){ return isTrue; };
}

It's a matter of preference and will vary on the specific situation. If you are simply returning a value for each enum, the constructor version is plausible, but I find it less readable. Concerns over this performing better is unfounded as you can see by testing it:

public void testMain() {
        System.out.println("Testing with constructor: ");
        long start = System.currentTimeMillis();
        for(int i=0; i<1000*1000; i++){
            MyEnum tmpEnum = null;
            if(i%3==0){ tmpEnum = MyEnum.A;
            }else if(i%4==0){ tmpEnum = MyEnum.B;
            }else{ tmpEnum = MyEnum.C; }
            String tmp = Integer.toString(i)+" "+tmpEnum.getBooleanValue();
        }
        long time = System.currentTimeMillis()-start;
        System.out.println("Constructor version took "+time);

        System.out.println("Testing with Constant specific method implementation: ");
        long start2 = System.currentTimeMillis();
        for(int i=0; i<1000*1000; i++){
            MyEnumAlt tmpEnum2 = null;
            if(i%3==0){ tmpEnum2 = MyEnumAlt.A;
            }else if(i%4==0){ tmpEnum2 = MyEnumAlt.B;
            }else{ tmpEnum2 = MyEnumAlt.C; }
            String tmp2 = Integer.toString(i)+" "+tmpEnum2.getBooleanValue();
        }
        long time2 = System.currentTimeMillis()-start2;
        System.out.println("Constant specific method version took "+time2);
    }
但可醉心2024-12-02 23:59:45

更好的解决方案是这样的:

enum:

public interface ACServices {

    public static enum MessageType {

        // periodic needs to saved in DB
        PIPE_INFO_TYPE_AC_DEVICE_LIST, // periodic from littlecloud
        PIPE_INFO_TYPE_DEV_ONLINE,
        PIPE_INFO_TYPE_DEV_OFFLINE,
        PIPE_INFO_TYPE_EVENT_LOG,
        PIPE_INFO_TYPE_DEV_DETAIL,
    };

implementation:

ACServices.MessageType msgType = ACServices.MessageType.valueOf(acResponse.getType());
switch (msgType){
    case INT_INFO_DEV_STATUS:
        break;
    case INT_INFO_DEV_TZ:
        break;
    case PIPE_INFO_DEV_COUNT:
        break;
    case PIPE_INFO_TYPE_AC_DEVICE_LIST:
        break;
    case PIPE_INFO_TYPE_CONFIG_GET_TEXT:
        break;
    default:
        break;
}

Man Pak Hong, Dave ([电子邮件受保护])

A better solution would be something like this:

enum:

public interface ACServices {

    public static enum MessageType {

        // periodic needs to saved in DB
        PIPE_INFO_TYPE_AC_DEVICE_LIST, // periodic from littlecloud
        PIPE_INFO_TYPE_DEV_ONLINE,
        PIPE_INFO_TYPE_DEV_OFFLINE,
        PIPE_INFO_TYPE_EVENT_LOG,
        PIPE_INFO_TYPE_DEV_DETAIL,
    };

implementation:

ACServices.MessageType msgType = ACServices.MessageType.valueOf(acResponse.getType());
switch (msgType){
    case INT_INFO_DEV_STATUS:
        break;
    case INT_INFO_DEV_TZ:
        break;
    case PIPE_INFO_DEV_COUNT:
        break;
    case PIPE_INFO_TYPE_AC_DEVICE_LIST:
        break;
    case PIPE_INFO_TYPE_CONFIG_GET_TEXT:
        break;
    default:
        break;
}

Man Pak Hong, Dave ([email protected])

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