Answers:
您可以像这样翻转一个值:
myVal = !myVal;
因此您的代码将缩短为:
switch(wParam) {
case VK_F11:
flipVal = !flipVal;
break;
case VK_F12:
otherVal = !otherVal;
break;
default:
break;
}
显然,您需要一种工厂模式!
KeyFactory keyFactory = new KeyFactory();
KeyObj keyObj = keyFactory.getKeyObj(wParam);
keyObj.doStuff();
class VK_F11 extends KeyObj {
boolean val;
public void doStuff() {
val = !val;
}
}
class VK_F12 extends KeyObj {
boolean val;
public void doStuff() {
val = !val;
}
}
class KeyFactory {
public KeyObj getKeyObj(int param) {
switch(param) {
case VK_F11:
return new VK_F11();
case VK_F12:
return new VK_F12();
}
throw new KeyNotFoundException("Key " + param + " was not found!");
}
}
:D
</sarcasm>
如果您知道值是0或1,则可以这样做flipval ^= 1
。
^
是异或运算符。0^1
是1
和1^1
是0
。如果忽略进位,则与添加相同。或者,您可以将其视为-如果任一位为1,则结果与另一位相反。或者,您可以将其视为一个问题:这两个位是否不同?
我找到的最简单的解决方案:
x ^= true;
x = !x;
不仅更短,而且更清晰。
longVariableName ^= true;
,显然比短longVariableName = !longVariableName;
。每个程序员都应该知道XOR。
a ^= b
表示a = a ^ b
,其中^
表示XOR。符号a °= b
为a = a ° b
用于任何操作员°
是众多C / C ++ / C#语法很常见的。
gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value = !gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value;
当然,最干净的方法是将其扩展为多行并使用临时变量存储对象,但是gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value ^= 1
比原始代码更具可读性,更少出错和更少字符。
仅供参考-如果您的必填字段不是整数,而是较大类型中的单个位,请改用'xor'运算符:
int flags;
int flag_a = 0x01;
int flag_b = 0x02;
int flag_c = 0x04;
/* I want to flip 'flag_b' without touching 'flag_a' or 'flag_c' */
flags ^= flag_b;
/* I want to set 'flag_b' */
flags |= flag_b;
/* I want to clear (or 'reset') 'flag_b' */
flags &= ~flag_b;
/* I want to test 'flag_b' */
bool b_is_set = (flags & flag_b) != 0;
我更喜欢John T的解决方案,但是如果您想使用所有代码,那么您的语句从逻辑上可以简化为:
//if key is down, toggle the boolean, else leave it alone.
flipVal = ((wParam==VK_F11) && !flipVal) || (!(wParam==VK_F11) && flipVal);
if(wParam==VK_F11) Break;
//if key is down, toggle the boolean, else leave it alone.
otherVal = ((wParam==VK_F12) && !otherVal) || (!(wParam==VK_F12) && otherVal);
if(wParam==VK_F12) Break;
显然,您需要一个灵活的解决方案来支持伪装为布尔值的类型。以下考虑到了这一点:
template<typename T> bool Flip(const T& t);
然后,您可以将其专门化为可能假装为布尔值的不同类型。例如:
template<> bool Flip<bool>(const bool& b) { return !b; }
template<> bool Flip<int>(const int& i) { return !(i == 0); }
使用此构造的示例:
if(Flip(false)) { printf("flipped false\n"); }
if(!Flip(true)) { printf("flipped true\n"); }
if(Flip(0)) { printf("flipped 0\n"); }
if(!Flip(1)) { printf("flipped 1\n"); }
不,我不认真。