我本人是三元运算符的拥护者:()?:; 我确实意识到它有它的位置,但是我遇到了许多程序员,他们完全反对使用它,有些人经常使用它。
您对此有何感想?您看到过使用它有趣的代码吗?
x = x if x else y
它,但是后来问了一下,并在其他人的帮助下意识到,它实际上只是减少到x = x或y(stackoverflow.com/questions/18199381/self-referencing-ternary/…)
我本人是三元运算符的拥护者:()?:; 我确实意识到它有它的位置,但是我遇到了许多程序员,他们完全反对使用它,有些人经常使用它。
您对此有何感想?您看到过使用它有趣的代码吗?
x = x if x else y
它,但是后来问了一下,并在其他人的帮助下意识到,它实际上只是减少到x = x或y(stackoverflow.com/questions/18199381/self-referencing-ternary/…)
Answers:
仅将其用于简单表达式:
int a = (b > 10) ? c : d;
不要链接或嵌套三元运算符,因为它很难阅读和混淆:
int a = b > 10 ? c < 20 ? 50 : 80 : e == 2 ? 4 : 8;
此外,在使用三元运算符时,请考虑以提高可读性的方式格式化代码:
int a = (b > 10) ? some_value
: another_value;
val x = if(true) 0 else 1
完全合法
由于您不能在每个子表达式上放置断点,因此调试起来会稍微困难一些。我很少使用它。
我喜欢它们,尤其是使用类型安全的语言。
我不知道这是怎么回事:
int count = (condition) ? 1 : 0;
比这更难:
int count;
if (condition)
{
count = 1;
}
else
{
count = 0;
}
编辑-
我认为三元运算符使所有内容都比其他运算符更简单,更整洁。
const int count = ...;
if/else
那里不需要的牙套有点误解。
if/else
大括号是大多数程序员如何将改写三元..
链式我很好-嵌套,不是很多。
我倾向于在C中更多地使用它们,因为b / c是具有价值的if语句,因此可以减少不必要的重复或变量:
x = (y < 100) ? "dog" :
(y < 150) ? "cat" :
(y < 300) ? "bar" : "baz";
而不是
if (y < 100) { x = "dog"; }
else if (y < 150) { x = "cat"; }
else if (y < 300) { x = "bar"; }
else { x = "baz"; }
在这样的作业中,我发现重构和清晰的工作要少得多。
另一方面,当我在红宝石中工作时,我更倾向于使用if...else...end
它,因为它也是一种表达方式。
x = if (y < 100) then "dog"
elif (y < 150) then "cat"
elif (y < 300) then "bar"
else "baz"
end
(尽管,坦白地说,对于这种简单的事情,我仍然可以使用三元运算符)。
三元?:
运算符只是程序if
构造的功能等效项。因此,只要您不使用嵌套?:
表达式,任何操作的函数表示形式/针对任何操作的函数表示形式的参数都在此处适用。但是嵌套三元运算可能会导致代码完全混乱(读者练习:尝试编写一个解析器以处理嵌套三元条件,您会发现它们的复杂性)。
但是在很多情况下,保守地使用?:
运算符可能会导致实际上比其他地方更易于阅读的代码。例如:
int compareTo(Object object) {
if((isLessThan(object) && reverseOrder) || (isGreaterThan(object) && !reverseOrder)) {
return 1;
if((isLessThan(object) && !reverseOrder) || (isGreaterThan(object) && reverseOrder)) {
return -1;
else
return 0;
}
现在将其与此:
int compareTo(Object object) {
if(isLessThan(object))
return reverseOrder ? 1 : -1;
else(isGreaterThan(object))
return reverseOrder ? -1 : 1;
else
return 0;
}
由于代码更加紧凑,因此语法上的噪音也更少,并且通过明智地使用三元运算符(仅与reverseOrder属性相关),最终结果并不是特别简洁。
确实,这是一个风格问题;我倾向于遵循的潜意识规则是:
foo = (bar > baz) ? true : false
,但不评估foo = (bar > baz && lotto && someArray.Contains(someValue)) ? true : false
<%= (foo) ? "Yes" : "No" %>
(foo) ? FooIsTrue(foo) : FooIsALie(foo)
)我喜欢它,因为它简洁而优雅,适合简单的赋值操作。
foo = (bar > baz);
更简单
像许多意见问题一样,答案不可避免地是: 它取决于
对于类似:
return x ? "Yes" : "No";
我觉得很多更简洁(对我来说解析起来更快):
if (x) {
return "Yes";
} else {
return "No";
}
现在,如果您的条件表达式很复杂,那么三元运算不是一个好的选择。就像是:
x && y && z >= 10 && s.Length == 0 || !foo
对于三元运算符不是一个很好的选择。
顺便说一句,如果您是C程序员,那么GCC实际上具有扩展名,使您可以排除三元组的if-true部分,如下所示:
/* 'y' is a char * */
const char *x = y ? : "Not set";
将设置x
于y
假设y
不是NULL
。好东西。
在我看来,仅在需要表达式的情况下使用三元运算符才有意义。
在其他情况下,似乎三元运算符会降低清晰度。
我经常在不得不在构造函数中使用的地方(例如,新的.NET 3.5 LINQ to XML构造)使用它来定义可选参数为null时的默认值。
人为的例子:
var e = new XElement("Something",
param == null ? new XElement("Value", "Default")
: new XElement("Value", param.ToString())
);
或(感谢星号)
var e = new XElement("Something",
new XElement("Value",
param == null ? "Default"
: param.ToString()
)
);
无论是否使用三元运算符,确保代码可读性都是重要的事情。可以使任何构造都不可读。
我会在任何可能的地方使用三元运算符,除非它使代码极难阅读,但这通常只是表明我的代码可以使用一些重构。
这总是让我感到困惑,有些人认为三元运算符是“隐藏的”功能还是有些神秘。这是我开始使用C进行编程时学到的第一件事,而且我认为它根本不会降低可读性。这是语言的自然组成部分。
我同意jmulder:不应将其代替 if
其代替,但其用于返回表达式或表达式内部:
echo "Result: " + n + " meter" + (n != 1 ? "s" : "");
return a == null ? "null" : a;
前者只是一个例子,应该使用更好的i18n复数支持!
我认为应在需要时使用三元运算符。这显然是一个非常主观的选择,但是我发现一个简单的表达式(特别是作为返回表达式)比完整的测试要清晰得多。C / C ++中的示例:
return (a>0)?a:0;
相比:
if(a>0) return a;
else return 0;
您还会遇到解决方案介于三元运算符和创建函数之间的情况。例如在Python中:
l = [ i if i > 0 else 0 for i in lst ]
替代方法是:
def cap(value):
if value > 0:
return value
return 0
l = [ cap(i) for i in lst ]
足够有必要在Python中(例如),可以经常看到这样的习惯用法:
l = [ ((i>0 and [i]) or [0])[0] for i in lst ]
该行使用Python中逻辑运算符的属性:它们是惰性的,如果最后一个值等于最终状态,则返回最后计算的值。
我见过这样的野兽(实际上是更糟糕的,因为它是isValidDate,并且也逐月检查,但我不想烦恼想起整个事情):
isLeapYear =
((yyyy % 400) == 0)
? 1
: ((yyyy % 100) == 0)
? 0
: ((yyyy % 4) == 0)
? 1
: 0;
显然,一系列if语句会更好(尽管它仍然比我曾经见过的宏版本更好)。
我不介意小事情:
reportedAge = (isFemale && (Age >= 21)) ? 21 + (Age - 21) / 3 : Age;
甚至有些棘手的事情,例如:
printf ("Deleted %d file%s\n", n, (n == 1) ? "" : "s");
reportedAge
这个例子需要一些思考-可能是因为它比解决特定问题更重要isThisYearALeapYear
我喜欢在调试代码中使用运算符来打印错误值,因此我不必一直查找它们。通常,我这样做是为了调试打印,一旦完成开发,这些打印就不会保留。
int result = do_something();
if( result != 0 )
{
debug_printf("Error while doing something, code %x (%s)\n", result,
result == 7 ? "ERROR_YES" :
result == 8 ? "ERROR_NO" :
result == 9 ? "ERROR_FILE_NOT_FOUND" :
"Unknown");
}
我几乎从不使用三元运算符,因为每当我使用它时,它总是让我比以后尝试维护它时思考更多。
我喜欢避免冗长,但是当它使代码更容易上手时,我会选择冗长。
考虑:
String name = firstName;
if (middleName != null) {
name += " " + middleName;
}
name += " " + lastName;
现在,这有点冗长,但是我发现它比:
String name = firstName + (middleName == null ? "" : " " + middleName)
+ " " + lastName;
要么:
String name = firstName;
name += (middleName == null ? "" : " " + middleName);
name += " " + lastName;
似乎只是将太多的信息压缩到了很小的空间中,而没有弄清楚发生了什么。每当我看到使用三元运算符时,我总会发现一个看起来更容易阅读的替代方法……然后再说一次,这是一个非常主观的观点,因此,如果您和您的同事发现三元运算符非常易读,那就去做吧。
只有当:
$ var =(简单>测试?simple_result_1:simple_result_2);
吻。
我通常在这样的事情中使用:
before:
if(isheader)
drawtext(x,y,WHITE,string);
else
drawtext(x,y,BLUE,string);
after:
drawtext(x,y,isheader==true?WHITE:BLUE,string);
正如其他人指出的那样,它们适合短时的简单条件。我特别喜欢它们作为默认值(类似于||和或 javascript和python中的用法),例如
int repCount = pRepCountIn ? *pRepCountIn : defaultRepCount;
另一个常见用途是在C ++中初始化引用。由于引用必须在同一条语句中声明和初始化,因此不能使用if语句。
SomeType& ref = pInput ? *pInput : somethingElse;
我最近看到了三元运算符的一种变体(很好),它使标准的“()?:”变体看起来像是清楚的典范:
var Result = [CaseIfFalse, CaseIfTrue][(boolean expression)]
或者,给出一个更具体的例子:
var Name = ['Jane', 'John'][Gender == 'm'];
请注意,这是Javascript,因此(谢天谢地)其他语言可能无法实现这种功能。
对于简单的情况,我喜欢使用它。实际上,作为功能或类似事物的参数,例如将其读/编码要容易得多。另外,为了避免出现新行,我希望保留所有if / else。
在我的书中,否定它是一个很大的禁忌。
因此,继续,对于单个if / else,我将使用三元运算符。在其他情况下,常规if / else if / else(或切换)
我喜欢Groovy的三元运算符的特殊情况,称为Elvis运算符:?:
expr ?: default
如果该代码不为null,则该代码的计算结果为expr,如果为null,则其默认值为。从技术上讲,它并不是真正的三元运算符,但与它绝对相关,并且可以节省大量时间/键入代码。
??
在C#中,空COALESCE操作:stackoverflow.com/questions/278703/...
有这么多答案说,这取决于。我发现,如果在快速浏览代码后看不到三元比较,则不应使用它。
作为附带的问题,我可能还要指出,由于在C语言中比较测试是一个陈述,因此它的存在实际上有点奇怪。在Icon中,if
构造(就像大多数Icon一样)实际上是一个表达式。因此,您可以执行以下操作:
x[if y > 5 then 5 else y] := "Y"
...我发现它比实习生比较运算符更具可读性。:-)
最近讨论了将?:
操作符添加到Icon 的可能性,但是一些人正确地指出,由于这种方式,绝对没有必要if
。
这意味着,如果您可以使用C语言(或具有ternery运算符的任何其他语言)执行此操作,那么实际上您根本不需要ternery运算符。