/**/
支架。有没有更干净的方法来处理这种逻辑?if (opcode == OP_0) { /* continue */}
else if (opcode == OP_1NEGATE) { /* continue */}
else if (opcode >= OP_1 && opcode <= OP_16) { /* continue */}
else { throw new Exception("decodeFromOpN called on non OP_N opcode"); }
#1 楼
您可以使用的是一个返回操作码是否有效的函数。private boolean isOpCode(Object opCode){
return opcode == OP_0 || opcode == OP_1NEGATE || (opcode >= OP_1 && opcode <= OP_16);
}
然后在您发布的代码中调用该函数,如果返回则抛出异常错误。
if(!isOpCode(opCode)){
throw new OpCodeInvalidException("decodeFromOpN called on non OP_N opcode");
}
用任何操作码替换
Object
。并创建一个从
Exception
扩展的新类。抛出Exception
通常是不好的做法。评论
\ $ \ begingroup \ $
应该使用条件OR运算符(||)代替按位逻辑OR运算符(|)。从语义上讲,它更接近含义,可以将其短路以避免避免评估整个表达式。
\ $ \ endgroup \ $
–马克·拉卡塔(Mark Lakata)
2014年3月11日下午4:59
\ $ \ begingroup \ $
我在这里看到很多冗余。为什么要检查每个操作码以查看是否存在这种操作码,而又要循环浏览一次以查找其执行的动作?切换似乎更加简单。
\ $ \ endgroup \ $
– Liamdev631
2014年3月12日在2:43
\ $ \ begingroup \ $
@ Liamdev631,我同意您的想法,对所有操作码进行switch声明,然后从那里开始。但是,他要求一种更简洁的逻辑处理方式。另外,如果OP _ ???是整数,则调用isOpCode运行相对较快。
\ $ \ endgroup \ $
–凯拉
2014年3月12日在20:08
#2 楼
仅当所有其他条件都为false时,才能执行else
分支:if (opcode != OP_0
&& opcode != OP_1NEGATE
&& (opcode < OP_1 || opcode > OP_16))
{
throw ...;
}
#3 楼
我不喜欢if
语句后的空白块。这非常令人困惑,并且使您的代码混乱。我也不喜欢您抛出了一般的
Exception
。创建一个并抛出该异常。public class InvalidOpCodeException : Exception
{
private int OpCode { get; private set; }
public InvalidOpCodeException(int opCode)
: base(string.Format("OpCode supplied is invalid {0}.", opCode)
{
OpCode = opCode;
}
}
我将其更改为仅查找错误情况
if (opcode != OP_0
&& opcode != OP_1NEGATE
&& (opcode < OP_1 || opcode > OP_16))
{
throw new InvalidOpCodeException(opcode);
}
// Rest of the code here
#4 楼
使用switch语句可能会更有效,如果操作码没有语句,则抛出异常。switch (opcode)
{
case OP_0: { /* do stuffs */}
case OP_1NEGATE: { /* do other stuffs */}
....
default: { throw new Exception("a no no"); }
}
#5 楼
我将假设OP_0
... OP_16
是连续的,并且OP_0
是最小的可能值。在这种情况下,将条件折叠在一起很简单:if (opcode > OP_16 && opcode != OP_1NEGATE)
throw new Exception("decodeFromOpN called on non OP_N opcode");
但是,如果
OP_0
可能与OP_1
不连续,或者可能小于OP_0的值,则可能失败。#6 楼
如果您将这三种情况分开是因为操作码值/范围表示不同的事情,并且出于不同的原因而选择了相同的动作(接受/跳过),那么我认为您的风格很好。描述每个案例含义的注释对于下一个人阅读代码很有用:if (opcode == OP_0) { /* OP_0 (zero) is a no-op, ok */}
else if (opcode == OP_1NEGATE) { /* flip register value */}
else if (opcode >= OP_1 && opcode <= OP_16) { /* known allocated opcodes */}
else { throw new Exception("decodeFromOpN called on non OP_N opcode"); }
通过这种方式,很明显案例在编写时具有不同的含义。 。随着代码的发展,将来的维护者可以在案例含义改变时添加/细分/合并案例,并且/或者在必要时针对每个案例添加调试信息或更改操作。
但是,每个人的回答,如果案例在此代码的本地上下文中具有大致相同的含义,则合并条件是有意义的。
评论
\ $ \ begingroup \ $
如果以几种方法执行相同的测试序列,并且每种情况都有语义[可能是显式的无操作],则这种设计可能特别好。例如,如果代码基于操作模式选择一系列if语句,则可以将“切换到XXX模式(如果尚未进入该模式)”的命令作为XXX模式if-block中的no-op处理。 ,但要对与其他模式关联的if块执行操作。
\ $ \ endgroup \ $
–超级猫
2014年3月11日20:40
评论
我看到大多数答案都复制了问题的缩进。我希望else if链与初始if对齐。当我看到一个缩进的其他字符时,我倾向于开始在同一水平上寻找if。通常,仅在控制结构内缩进一次,但将控制结构关键字保持在其开始的级别。