On 1/14/21 7:27 PM, ddcovery wrote:
On Thursday, 14 January 2021 at 20:23:08 UTC, Steven Schveighoffer wrote:
You could kinda automate it like:
struct NullCheck(T)
{
private T* _val;
auto opDispatch(string mem)() if (__traits(hasMember, T, mem)) {
alias Ret = typeof(() { return __traits(getMember, *_val, mem);
}());
if(_val is null) return NullCheck!(Ret)(null);
else return NullCheck!(Ret)(__trats(getMember, *_val, mem));
}
bool opCast(V: bool)() { return _val !is null; }
}
auto nullCheck(T)(T *val) { return AutoNullCheck!T(val);}
// usage
if(nullCheck(person).father.father && person.father.father.name ==
"Peter")
Probably doesn't work for many circumstances, and I'm sure I messed
something up.
-Steve
I'm seeing "opDispatch" everywhere last days :-). It's really powerful!!!
If we define an special T _(){ return _val; } method, then you can write
if( nullCheck(person).father.father.name._ == "Peter")
And renaming
if( ns(person).father.father.name._ == "Peter" )
This doesn't work, if person, person.father, or person.father.father is
null, because now you are dereferencing null again.
But something like this might work:
NullCheck(T)
{
... // opdispatch and stuff
bool opEquals(auto ref T other) {
return _val is null ? false : *_val == other;
}
}
Something similar to BlackHole or WhiteHole. Essentially there's a
default action for null for all types/fields/methods, and everything
else is passed through.
Swift has stuff like this built-in. But D might look better because you
wouldn't need a chain of question marks.
-Steve