On Monday, 16 September 2013 at 16:50:43 UTC, Namespace wrote:
On Monday, 16 September 2013 at 15:47:36 UTC, ilya-stromberg
wrote:
On Monday, 16 September 2013 at 15:12:05 UTC, Maxim Fomin
wrote:
On Monday, 16 September 2013 at 10:29:12 UTC, matovitch wrote:
All your examples are great, thank you ! Is there a way to
omit validate such that the compiler would call it
implicitly ?
For example :
class C {
...
}
void fun(@nonNull C c) {
...
};
C c;
fun(c); //compilation error since C is null
No, this isn't doable with UDAs because what you want
requires runtime check. It is doable using other language
features.
It's intresting how can I check that pointer is not null at
the compile time. Can you print a example, please?
I know that we can use contract programming, but it requires
runtime check.
That isn't possible. ;)
Similar effect can be achieved by different way. If some function
takes S as parameter, one cannot pass directly instance of A or
null - error will be issued which is some sort of compile-time
protection.
class A
{
int i;
}
struct S
{
A a;
A getA()
{
if (a is null)
a = new A;
return a;
}
alias getA this;
}
void main()
{
S s;
assert (s.i is 0);
S ss = S.init;
assert (ss.i is 0);
}
Unfortunately D does not have non-nullable classes which is a
problem #1. Ideally structs should have default constructors
(hello to those who miss them - problem #2) which could
initialize class instance. Since they are absent, wrapping struct
can be enhanced by inserting disabled constructor to ensure that
no default struct instances with null references are created.
However, since disabled constructors are also flawed (they don't
prevent from producing T.init values by design and in some
situations dmd is not smart enough to detect other cases by
mistake) which is a problem #3, non-null classes can be simulated
by code above using alias this + rt check. At least this works
with two most problematic cases of struct initilialization:
without initializer and with T.init value.