为什么要在条件中使用赋值?

发布于 2024-07-05 16:20:26 字数 187 浏览 3 评论 0原文

在许多语言中,赋值在有条件的情况下是合法的。 我一直不明白这背后的原因。 为什么你会写:

if (var1 = var2) {
  ...
}

而不是:

var1 = var2;
if (var1) {
  ...
}

In many languages, assignments are legal in conditions. I never understood the reason behind this. Why would you write:

if (var1 = var2) {
  ...
}

instead of:

var1 = var2;
if (var1) {
  ...
}

?

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

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

发布评论

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

评论(12

过度放纵 2024-07-12 16:20:26

我发现它在经常​​涉及错误检测等的操作链中最有用。

if ((rc = first_check(arg1, arg2)) != 0)
{
    report error based on rc
}
else if ((rc = second_check(arg2, arg3)) != 0)
{
    report error based on new rc
}
else if ((rc = third_check(arg3, arg4)) != 0)
{
    report error based on new rc
}
else
{
    do what you really wanted to do
}

替代方案(不使用条件中的分配)是:

rc = first_check(arg1, arg2);
if (rc != 0)
{
    report error based on rc
}
else
{
    rc = second_check(arg2, arg3);
    if (rc != 0)
    {
        report error based on new rc
    }
    else
    {
        rc = third_check(arg3, arg4);
        if (rc != 0)
        {
            report error based on new rc
        }
        else
        {
            do what you really wanted to do
        }
    }
}

通过长时间的错误检查,替代方案可以在页面的右侧运行,而分配在-条件版本不这样做。

错误检查也可以是“动作”——first_action()second_action()third_action()——当然,不仅仅是检查。 也就是说,它们可以被检查该功能正在管理的流​​程中的步骤。 (大多数情况下,在我使用的代码中,这些函数是沿着前置条件检查的路线,或者函数工作所需的内存分配,或者沿着类似的路线)。

I find it most useful in chains of actions which often involve error detection, etc.

if ((rc = first_check(arg1, arg2)) != 0)
{
    report error based on rc
}
else if ((rc = second_check(arg2, arg3)) != 0)
{
    report error based on new rc
}
else if ((rc = third_check(arg3, arg4)) != 0)
{
    report error based on new rc
}
else
{
    do what you really wanted to do
}

The alternative (not using the assignment in the condition) is:

rc = first_check(arg1, arg2);
if (rc != 0)
{
    report error based on rc
}
else
{
    rc = second_check(arg2, arg3);
    if (rc != 0)
    {
        report error based on new rc
    }
    else
    {
        rc = third_check(arg3, arg4);
        if (rc != 0)
        {
            report error based on new rc
        }
        else
        {
            do what you really wanted to do
        }
    }
}

With protracted error checking, the alternative can run off the RHS of the page whereas the assignment-in-conditional version does not do that.

The error checks could also be 'actions' — first_action(), second_action(), third_action() — of course, rather than just checks. That is, they could be checked steps in the process that the function is managing. (Most often in the code I work with, the functions are along the lines of pre-condition checks, or memory allocations needed for the function to work, or along similar lines).

小鸟爱天空丶 2024-07-12 16:20:26

for 循环比 if 语句更有用。

while(var = GetNext())
{
  ...do something with 'var' 
}

否则必须写成

var = GetNext();
while(var)
{
  ...do something
  var = GetNext();
}

It's more useful for loops than if statements.

while(var = GetNext())
{
  ...do something with 'var' 
}

Which would otherwise have to be written

var = GetNext();
while(var)
{
  ...do something
  var = GetNext();
}
夜空下最亮的亮点 2024-07-12 16:20:26

原因是:

  1. 性能提升(有时)

  2. 更少的代码(总是)

举个例子:有一个方法 someMethod() ,在 if 条件下你想检查该方法的返回值是否为 。 如果没有,您将再次使用返回值。

If(null != someMethod()){
    String s = someMethod();
    ......
    //Use s
}

由于您两次调用相同的方法,这会影响性能。 而是使用:

String s;
If(null != (s = someMethod())) {
    ......
    //Use s
}

The reason is:

  1. Performance improvement (sometimes)

  2. Less code (always)

Take an example: There is a method someMethod() and in an if condition you want to check whether the return value of the method is null. If not, you are going to use the return value again.

If(null != someMethod()){
    String s = someMethod();
    ......
    //Use s
}

It will hamper the performance since you are calling the same method twice. Instead use:

String s;
If(null != (s = someMethod())) {
    ......
    //Use s
}
美胚控场 2024-07-12 16:20:26

我今天在 Arduino(C++ 语言的子集)中编程时使用了它。

案例

I 有一个发射器和一个接收器。
发送器想要发送数据直到接收到数据。 我想在该过程完成时设置一个标志。

while (!(newtork_joined = transmitter.send(data))) {
Serial.println("Not Joined");
}

这里:

  • “transmitter.send” - 传输成功时返回true
  • “newtork_joined” - 是我在成功时设置的标志

结果

  1. 当传输不成功时,不设置该标志,而loop为true时,它保持执行

  2. 成功时,设置标志,whileloop为假,退出

漂亮吗?

I used it today while programing in Arduino (Subset of C++ language).

Case

I have a transmitter and a receiver.
The transmitter wants to send the data until it is received. I want to set a flag when the process is done.

while (!(newtork_joined = transmitter.send(data))) {
Serial.println("Not Joined");
}

Here:

  • "transmitter.send" - returns true when the transmission is successful
  • "newtork_joined " - is the flag I set when successful

Result

  1. When the transmission is not successful, the flag is not set, while loop is true, it keeps executing

  2. When successful, the flag is set, while loop is false, we exit

Isn't beautiful?

百合的盛世恋 2024-07-12 16:20:26

我发现它对于返回可选值的函数非常有用(C++17 中的 boost::可选 或 std::可选 ):

std::optional<int> maybe_int(); // function maybe returns an int

if (auto i = maybe_int()) {
    use_int(*i);
}

这减少了我的变量的范围,使代码更紧凑并且不会妨碍可读性(我发现)。

与指针相同:

int* ptr_int();

if (int* i = ptr_int()) {
    use_int(*i);
}

I find it very useful with functions returning optionals (boost::optional or std::optional in C++17):

std::optional<int> maybe_int(); // function maybe returns an int

if (auto i = maybe_int()) {
    use_int(*i);
}

This reduces the scope of my variable, makes code more compact and does not hinder readability (I find).

Same with pointers:

int* ptr_int();

if (int* i = ptr_int()) {
    use_int(*i);
}
梦回梦里 2024-07-12 16:20:26

另一个优点是使用GDB

在下面的代码中,如果我们单步执行,错误代码是未知的。

while (checkstatus() != -1) {
    // Process
}

现在

while (true) {
    int error = checkstatus();
    if (error != -1)
        // Process
    else
        // Fail
}

,在单步执行期间,我们可以知道 checkstatus() 返回的错误代码是什么。

The other advantage comes during the usage of GDB.

In the following code, the error code is not known if we were to single step.

while (checkstatus() != -1) {
    // Process
}

Rather

while (true) {
    int error = checkstatus();
    if (error != -1)
        // Process
    else
        // Fail
}

Now during single stepping, we can know what was the return error code from the checkstatus().

-小熊_ 2024-07-12 16:20:26

例如,在 PHP 中,它对于循环 SQL 数据库结果很有用:

while ($row = mysql_fetch_assoc($result)) {
    // Display row
}

这看起来比:

$row = mysql_fetch_assoc($result);
while ($row) {
    // Display row
    $row = mysql_fetch_assoc($result);
}

In PHP, for example, it's useful for looping through SQL database results:

while ($row = mysql_fetch_assoc($result)) {
    // Display row
}

This looks much better than:

$row = mysql_fetch_assoc($result);
while ($row) {
    // Display row
    $row = mysql_fetch_assoc($result);
}
放血 2024-07-12 16:20:26

简而言之,面向表达式编程语言允许更简洁的代码。 它们不会强迫您将命令与查询分开

The short answer is that expression-oriented programming languages allow more succinct code. They don't force you to separate commands from queries.

牵你的手,一向走下去 2024-07-12 16:20:26

当您编写 while 循环而不是 if 语句时,该习惯用法更有用。 对于 if 语句,您可以按照您的描述将其分解。 但是如果没有这个构造,您要么必须重复自己:

c = getchar();
while (c != EOF) {
    // ...
    c = getchar();
}

要么使用循环半结构:

while (true) {
    c = getchar();
    if (c == EOF) break;
    // ...
}

我通常更喜欢循环半形式。

The idiom is more useful when you're writing a while loop instead of an if statement. For an if statement, you can break it up as you describe. But without this construct, you would either have to repeat yourself:

c = getchar();
while (c != EOF) {
    // ...
    c = getchar();
}

or use a loop-and-a-half structure:

while (true) {
    c = getchar();
    if (c == EOF) break;
    // ...
}

I would usually prefer the loop-and-a-half form.

掩耳倾听 2024-07-12 16:20:26

如果您要调用函数,它会更有用:

if (n = foo())
{
    /* foo returned a non-zero value, do something with the return value */
} else {
    /* foo returned zero, do something else */
}

当然,您可以直接输入 n = foo(); 在单独的语句 then if (n) 上,但我认为上面是一个相当可读的习惯用法。

It's more useful if you are calling a function:

if (n = foo())
{
    /* foo returned a non-zero value, do something with the return value */
} else {
    /* foo returned zero, do something else */
}

Sure, you can just put the n = foo(); on a separate statement then if (n), but I think the above is a fairly readable idiom.

罗罗贝儿 2024-07-12 16:20:26

如果您调用的函数返回要处理的数据或返回指示错误(或已完成)的标志,那么它会很有用。

比如:

while ((c = getchar()) != EOF) {
    // process the character
}

// end of file reached...

就我个人而言,我不太喜欢这个习语,但有时替代方案更丑陋。

It can be useful if you're calling a function that returns either data to work on or a flag to indicate an error (or that you're done).

Something like:

while ((c = getchar()) != EOF) {
    // process the character
}

// end of file reached...

Personally it's an idiom I'm not hugely fond of, but sometimes the alternative is uglier.

执手闯天涯 2024-07-12 16:20:26

GCC 可以帮助您检测(使用 -Wall)是否无意中尝试使用赋值作为真值,以防它建议您编写

if ((n = foo())) {
   ...
}

I.e. 使用额外的括号来表明这确实是您想要的。

GCC can help you detect (with -Wall) if you unintentionally try to use an assignment as a truth value, in case it recommends you write

if ((n = foo())) {
   ...
}

I.e. use extra parenthesis to indicate that this is really what you want.

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