Cul*_*lip 25 language-design boolean-operations
可能重复:
为什么大多数编程语言只有二进制相等比较运算符?
自从我开始学习编程语言以来,我有一个很长时间的简单问题.
我想写"如果x是1或2 => TRUE(否则为FALSE)."
但是当我用编程语言编写它时,比如C,
( x == 1 || x == 2 )
Run Code Online (Sandbox Code Playgroud)
它确实有效,但看起来很尴尬,难以阅读.我想应该可以简化这样的操作,所以如果您有任何想法,请告诉我.谢谢,内森
Ign*_*ams 36
Python允许测试序列中的成员资格:
if x in (1, 2):
Run Code Online (Sandbox Code Playgroud)
And*_*ngs 18
C#中的扩展版本
第1步:创建扩展方法
public static class ObjectExtensions
{
public static bool Either(this object value, params object[] array)
{
return array.Any(p => Equals(value, p));
}
}
Run Code Online (Sandbox Code Playgroud)
第2步:使用扩展方法
if (x.Either(1,2,3,4,5,6))
{
}
else
{
}
Run Code Online (Sandbox Code Playgroud)
Dar*_*oid 17
虽然在这个帖子中有许多非常有趣的答案,但我想指出,如果你根据语言在循环中做这种逻辑,它们可能会有性能影响.就计算机而言,if (x == 1 || x == 2)当它被编译成机器代码时,它是迄今为止最容易理解和优化的.
Flo*_*rin 11
当我开始编程时,对我来说似乎很奇怪,而不是像:
(1 < x < 10)
Run Code Online (Sandbox Code Playgroud)
我不得不写:
(1 < x && x < 10)
Run Code Online (Sandbox Code Playgroud)
但这就是大多数编程语言的工作方式,过了一段时间你就会习惯它.
所以我相信写作完全没问题
( x == 1 || x == 2 )
Run Code Online (Sandbox Code Playgroud)
以这种方式编写也具有其他程序员可以轻松理解您所写内容的优点.使用函数来封装它可能会使事情变得更复杂,因为其他程序员需要找到该函数并查看它的作用.
只有像Python,Ruby等更新的编程语言允许您以更简单,更好的方式编写它.这主要是因为这些编程语言旨在提高程序员的工作效率,而较旧的编程语言的主要目标是应用程序性能,而不是程序员的生产力.
您的方法确实看起来更自然,但这实际上取决于您用于实现的语言.
C是一种系统编程语言,并且非常接近硬件(虽然很滑稽,因为我们曾经考虑过"高级"语言,而不是编写机器代码),但它并不完全具有表现力.
现代高级语言(再次,可论证,lisp并不是现代的,从历史上讲,但是可以让你做得很好)允许你通过使用内置的构造或库支持来做这些事情(例如,使用Ranges,Python,Ruby,Groovy,ML-languages,Haskell等语言中的元组或等价物.
您可以选择实现一个函数或子例程来获取值数组并检查它们.
这是一个基本原型,我将实现作为练习留给您:
/* returns non-zero value if check is in values */
int is_in(int check, int *values, int size);
Run Code Online (Sandbox Code Playgroud)
但是,正如您将很快看到的,这是非常基本的,并不是非常灵活:
一个步骤的复杂性梯子(在语言方面)更高,可选的是使用预处理器 宏在Ç(或C++),以实现类似的行为,但要小心副作用.
下一步可以是将函数指针作为额外参数传递,以定义调用点处的行为,为此定义几个变体和别名,并构建一个小型的比较器库.
接下来的步骤是使用模板在C++中实现类似的东西,使用单个实现在不同类型上执行此操作.
然后继续从那里到更高级别的语言.
通常,出于显而易见的原因,有利于函数式编程的语言将内置支持此类事物.
或者只是学会接受某些语言可以做别人不能做的事情,而且取决于工作和环境,这就是它的方式.它主要是语法糖,你可以做的并不多.此外,一些语言将通过更新其规格来解决它们的缺点,而其他语言将停滞不前.
也许一个图书馆已经实现了这样的事情,我不知道.
这是很多有趣的选择.我很惊讶没人提到切换...案例 - 所以这里是:
switch(x) {
case 1:
case 2:
// do your work
break;
default:
// the else part
}
Run Code Online (Sandbox Code Playgroud)
呃,这有什么问题?哦,好吧,如果你真的使用它很多,并讨厌外观在c#中做这样的事情:
#region minimizethisandneveropen
public bool either(value,x,y){
return (value == x || value == y);
}
#endregion
Run Code Online (Sandbox Code Playgroud)
在您使用它的地方:
if(either(value,1,2))
//yaddayadda
Run Code Online (Sandbox Code Playgroud)
或者类似于另一种语言的东西:).
我怀疑我是否会这样做,但回答你的问题,这是在C#中实现它的一种方法,涉及一些通用类型推断和一些滥用运算符重载.你可以写这样的代码:
if (x == Any.Of(1, 2)) {
Console.WriteLine("In the set.");
}
Run Code Online (Sandbox Code Playgroud)
当Any类被定义为:
public static class Any {
public static Any2<T> Of<T>(T item1, T item2) {
return new Any2<T>(item1, item2);
}
public struct Any2<T> {
T item1;
T item2;
public Any2(T item1, T item2) {
this.item1 = item1;
this.item2 = item2;
}
public static bool operator ==(T item, Any2<T> set) {
return item.Equals(set.item1) || item.Equals(set.item2);
}
// Defining the operator== requires these three methods to be defined as well:
public static bool operator !=(T item, Any2<T> set) {
return !(item == set);
}
public override bool Equals(object obj) { throw new NotImplementedException(); }
public override int GetHashCode() { throw new NotImplementedException(); }
}
}
Run Code Online (Sandbox Code Playgroud)
你可以想象有多个Any.Of方法的重载来处理3,4或甚至更多的参数.也可以提供其他操作员,并且伴侣All类可以做一些非常相似但&&代替的操作||.
看看反汇编,由于需要调用Equals,发生了相当多的装箱,因此最终比明显的(x == 1) || (x == 2)构造慢.但是,如果你改变一切<T>的来int和更换Equals用==,你得到的东西这似乎很好地内嵌到大致相同的速度(x == 1) || (x == 2).