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" )

And adding some extra check like ** isAssignable!(Ret, typeof(null) )** we can add special treatment for not nullable types

  if( ns(person).father.father.age._(0) == 92 ){ ... }
  assert( ns(person).father.father.father.age._ == int.init );

If for some strange reason I ever need null safety, I think this is the most beautiful solution or at least a great lesson on templates.

Thanks a lot for the lesson, Steve

Reply via email to