| |
| Posted by Basile B. in reply to mark | PermalinkReply |
|
Basile B.
| 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]);
}
}
---
|