Thread overview
Does D have an equvalent of: if (auto = expr; expr)
Feb 07, 2020
mark
Feb 07, 2020
Sebastiaan Koppe
Feb 07, 2020
Basile B.
Feb 07, 2020
mark
February 07, 2020
Some languages support this kind of thing:

if ((var x = expression) > 50)
  print(x, " is > 50")

Is there anything similar in D?
February 07, 2020
On Friday, 7 February 2020 at 08:52:44 UTC, mark wrote:
> Some languages support this kind of thing:
>
> if ((var x = expression) > 50)
>   print(x, " is > 50")
>
> Is there anything similar in D?

Yes and no.

It only works for bools or things that convert to bool.

You might have seen:

string[string] dict;
if (auto p = "key" in dict) {
  writeln(*p);
}

That works because the 'in' operator on aa's returns a pointer, which can be compared to bool.
February 07, 2020
On Friday, 7 February 2020 at 08:52:44 UTC, mark wrote:
> Some languages support this kind of thing:
>
> if ((var x = expression) > 50)
>   print(x, " is > 50")
>
> Is there anything similar in D?

Yes assuming that the expression is bool evaluable. This includes

- pointers: `if (auto p = giveMeSomePtr()){}`
- classes references: `if (auto p = giveMeSomeClasses()){}`
- integers `if (auto p = giveMeAnInt()){}`

and using the in operators as you've been answered previously.
The problem is that this support only one variable and that the If condition must be either a variable or a relational expression. Not both.

To overcome the limitation of a single variable I've made a little template:

---
/**
 * Encapsulates several variables in a tuple that's usable as a if condition,
 * as a workaround to the single declaration allowed by the language.
 *
 * Params:
 *      a = The expressions giving the variables.
 *          The variables must be evaluable to $(D bool).
 *
 * Returns:
 *      A tuple containing the variables.
 */
auto ifVariables(A...)(auto ref A a)
if (A.length)
{
    static struct IfVariables(A...)
    {
        private A tup;
        alias tup this;

        this() @disable;
        this(this) @disable;

        this(ref A a)
        {
            tup = a;
        }

        bool opCast(T : bool)() const
        {
            static foreach (i; 0 .. A.length)
                if (!tup[i])
                    return false;
            return true;
        }
    }
    return IfVariables!A(a);
}
///
unittest
{
    assert(ifVariables(new Object, true, new Object));
    assert(!ifVariables(new Object, false, new Object));
    // typical usage
    bool isDlangExpressive(){return true;}
    if (auto a = ifVariables(new Object, isDlangExpressive())) {}
    // use the variables
    if (auto a = ifVariables(new Object, new Object))
    {
        assert(a.length == 2);
        assert(a[0] !is a[1]);
    }
}

---
February 07, 2020
Thanks for the excellent replies.