Open question: what code pattern you use usually for null safety problem

Steven Schveighoffer schveiguy at gmail.com
Fri Jan 15 14:19:35 UTC 2021


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


More information about the Digitalmars-d-learn mailing list