Nullable!T
Adam Ruppe
destructionator at gmail.com
Tue Jul 6 06:25:36 PDT 2010
On 7/6/10, bearophile <bearophileHUGS at lycos.com> wrote:
> 1) Nullable!(SomeClass) is forbidden in C#.
I figure a Nullable struct would just alias the original type if T t;
t = null; already compiles. So a nullable pointer, class, or Nullable
is just a no-op. This would cover your cases 1 and 2 with a simple
rule.
> Optionally this can be accepted:
> Nullable!int x;
> if (x) { ...
> that is equivalent to:
> if (x.hasValue) { ...
> But this doesn't look fully tidy to me...
Blargh, what I'd want is
if(x is null)
An implementation that might work is
=============
template Nullable(T) {
static if(is(typeof( {
T t;
t = null;
}))) {
alias T Nullable; // if it is already nullable, do nothing special
}
else
{
struct Nullable {
T value;
T* hasValue = null; // i guess this could be boolean too
bool opCast(A)() if(is(A == bool)) { // for if(x)
return !(hasValue is null);
}
typeof(this) opAssign(T v) { // should be ok assigning known not-null values
value = v;
hasValue = &value;
return this;
}
typeof(this) opAssign(typeof(this) t) { // Nullable!T = Nullable!T
should always be good
value = t.value;
if(t.hasValue)
hasValue = &value;
else
hasValue = null;
return this;
}
typeof(this) opAssign(void* nullptr) { // so literal null assignment works
assert(nullptr is null);
hasValue = null;
return this;
}
}
}
}
// below is a kind of unittest
class A {}
import std.stdio;
void main() {
A a1;
Nullable!A a2;
a1 = a2;
a2 = a1; // compatible; types are aliases
Nullable!(Nullable!A) a3;
a1 = a3; // still compatible, aliases
int* b1;
Nullable!(int*) b2;
b1 = b2;
b2 = b1; // aliases again
int c1;
Nullable!(int) c2;
assert(!c2.hasValue); // it should start null
//c1 = c2; // doesn't compile; they are different types
c2 = c1; // does compile, and set to non-null implicitly
assert(c2.hasValue); // just assigned to it; shouldn't be bull
c2 = null; // should compile, set to null
assert(!c2.hasValue);
Nullable!(Nullable!int) c3;
c3 = 10; // should be fine
c2 = c3; // should compile
// c1 = c3; // should not and does not
if(c2) // same as if(c2.hasValue)
assert(0);
else
writefln("value is %d", c2.value);
}
==============
> C# has the ?? operator (Elvis operator) that can be used to replace this:
> int y = x ?? -1;
Meh, the regular ternary works fine, or this could be a member function:
x.get(-1); // gets if not null, returns -1 if it is null
x itself is a struct, so it can never be null, so no need to worry
about x.get throwing a segfault.
> This can be done in D too, but this can be added later too. The advantage of
> this syntax sugar is to encourage programmers to use Nullables.
Gah, Nullable!T is perfectly fine. I don't even know if you actually
want to encourage people to use nullables; they shouldn't be needed
all that often says my gut. Better to avoid things being null if
possible.
More information about the Digitalmars-d
mailing list