std.typecons.Nullable/nullable
- multiple declarations
Function nullable
Defines a value paired with a distinctive "null" state that denotes
the absence of a value. If default constructed, a Nullable!T
object starts in the null state. Assigning it renders it
non-null. Calling nullify
can nullify it again.
auto nullable(T)
(
T t
);
Practically Nullable!T
stores a T
and a bool
.
See also:
apply
, an alternative way to use the payload.
Example
struct CustomerRecord
{
string name;
string address;
int customerNum;
}
Nullable!CustomerRecord getByName(string name)
{
//A bunch of hairy stuff
return Nullable!CustomerRecord .init;
}
auto queryResult = getByName("Doe, John");
if (!queryResult .isNull)
{
//Process Mr. Doe's customer record
auto address = queryResult .get .address;
auto customerNum = queryResult .get .customerNum;
//Do some things with this customer's info
}
else
{
//Add the customer to the database
}
Example
import std .exception : assertThrown;
auto a = 42 .nullable;
assert(!a .isNull);
writeln(a .get); // 42
a .nullify();
assert(a .isNull);
assertThrown!Throwable(a .get);
Example
import std .algorithm .iteration : each, joiner;
Nullable!int a = 42;
Nullable!int b;
// Add each value to an array
int[] arr;
a .each!((n) => arr ~= n);
writeln(arr); // [42]
b .each!((n) => arr ~= n);
writeln(arr); // [42]
// Take first value from an array of Nullables
Nullable!int[] c = new Nullable!int[](10);
c[7] = Nullable!int(42);
writeln(c .joiner .front); // 42
Function nullable
Just like Nullable!T
, except that the null state is defined as a
particular value. For example, Nullable!(uint, uint
is an
uint
that sets aside the value uint
to denote a null
state. Nullable!(T, nullValue)
is more storage-efficient than Nullable!T
because it does not need to store an extra bool
.
auto nullable(alias nullValue, T)
(
T t
)
if (is(typeof(nullValue) == T));
Parameters
Name | Description |
---|---|
T | The wrapped type for which Nullable provides a null value. |
nullValue | The null value which denotes the null state of this
Nullable . Must be of type T . |
Example
Nullable!(size_t, size_t .max) indexOf(string[] haystack, string needle)
{
//Find the needle, returning -1 if not found
return Nullable!(size_t, size_t .max) .init;
}
void sendLunchInvite(string name)
{
}
//It's safer than C...
auto coworkers = ["Jane", "Jim", "Marry", "Fred"];
auto pos = indexOf(coworkers, "Bob");
if (!pos .isNull)
{
//Send Bob an invitation to lunch
sendLunchInvite(coworkers[pos]);
}
else
{
//Bob not found; report the error
}
//And there's no overhead
static assert(Nullable!(size_t, size_t .max) .sizeof == size_t .sizeof);
Example
import std .exception : assertThrown;
Nullable!(int, int .min) a;
assert(a .isNull);
assertThrown!Throwable(a .get);
a = 5;
assert(!a .isNull);
writeln(a); // 5
static assert(a .sizeof == int .sizeof);
Example
auto a = nullable!(int .min)(8);
writeln(a); // 8
a .nullify();
assert(a .isNull);
Struct Nullable
Defines a value paired with a distinctive "null" state that denotes
the absence of a value. If default constructed, a Nullable!T
object starts in the null state. Assigning it renders it
non-null. Calling nullify
can nullify it again.
struct Nullable(T)
;
Practically Nullable!T
stores a T
and a bool
.
See also:
apply
, an alternative way to use the payload.
Constructors
Name | Description |
---|---|
this
(value)
|
Constructor initializing this with value .
|
Properties
Name | Type | Description |
---|---|---|
front [get]
|
inout(T) | Range interface functions. |
get [get, set]
|
inout(T) | Gets the value if not null. If this is in the null state, and the optional
parameter fallback was provided, it will be returned. Without fallback ,
calling get with a null state is invalid.
|
isNull [get]
|
bool | Check if this is in the null state.
|
length [get]
|
size_t | Range interface functions. |
save [get]
|
inout(typeof(this)) | Range interface functions. |
Methods
Name | Description |
---|---|
nullify
()
|
Forces this to the null state.
|
opAssign
(value)
|
Assigns value to the internally-held state. If the assignment
succeeds, this becomes non-null.
|
opEquals
(rhs)
|
If they are both null, then they are equal. If one is null and the other is not, then they are not equal. If they are both non-null, then they are equal if their values are equal. |
opIndex
()
|
Range interface functions. |
opSlice
(from, to)
|
Range interface functions. |
toString
()
|
Gives the string "Nullable.null" if isNull is true . Otherwise, the
result is equivalent to calling std on the
underlying value.
|
Aliases
Name | Description |
---|---|
back
|
Range interface functions. |
empty
|
Range interface functions. |
opDollar
|
Range interface functions. |
popBack
|
Range interface functions. |
popFront
|
Range interface functions. |
Example
struct CustomerRecord
{
string name;
string address;
int customerNum;
}
Nullable!CustomerRecord getByName(string name)
{
//A bunch of hairy stuff
return Nullable!CustomerRecord .init;
}
auto queryResult = getByName("Doe, John");
if (!queryResult .isNull)
{
//Process Mr. Doe's customer record
auto address = queryResult .get .address;
auto customerNum = queryResult .get .customerNum;
//Do some things with this customer's info
}
else
{
//Add the customer to the database
}
Example
import std .exception : assertThrown;
auto a = 42 .nullable;
assert(!a .isNull);
writeln(a .get); // 42
a .nullify();
assert(a .isNull);
assertThrown!Throwable(a .get);
Example
import std .algorithm .iteration : each, joiner;
Nullable!int a = 42;
Nullable!int b;
// Add each value to an array
int[] arr;
a .each!((n) => arr ~= n);
writeln(arr); // [42]
b .each!((n) => arr ~= n);
writeln(arr); // [42]
// Take first value from an array of Nullables
Nullable!int[] c = new Nullable!int[](10);
c[7] = Nullable!int(42);
writeln(c .joiner .front); // 42
Struct Nullable
Just like Nullable!T
, except that the null state is defined as a
particular value. For example, Nullable!(uint, uint
is an
uint
that sets aside the value uint
to denote a null
state. Nullable!(T, nullValue)
is more storage-efficient than Nullable!T
because it does not need to store an extra bool
.
struct Nullable(T, T nullValue)
;
Constructors
Name | Description |
---|---|
this
(value)
|
Constructor initializing this with value .
|
Properties
Name | Type | Description |
---|---|---|
get [get]
|
inout(T) | Gets the value. this must not be in the null state.
This function is also called for the implicit conversion to T .
|
isNull [get]
|
bool | Check if this is in the null state.
|
Methods
Name | Description |
---|---|
nullify
()
|
Forces this to the null state.
|
opAssign
(value)
|
Assigns value to the internally-held state. If the assignment
succeeds, this becomes non-null. No null checks are made. Note
that the assignment may leave this in the null state.
|
Parameters
Name | Description |
---|---|
T | The wrapped type for which Nullable provides a null value. |
nullValue | The null value which denotes the null state of this
Nullable . Must be of type T . |
Example
Nullable!(size_t, size_t .max) indexOf(string[] haystack, string needle)
{
//Find the needle, returning -1 if not found
return Nullable!(size_t, size_t .max) .init;
}
void sendLunchInvite(string name)
{
}
//It's safer than C...
auto coworkers = ["Jane", "Jim", "Marry", "Fred"];
auto pos = indexOf(coworkers, "Bob");
if (!pos .isNull)
{
//Send Bob an invitation to lunch
sendLunchInvite(coworkers[pos]);
}
else
{
//Bob not found; report the error
}
//And there's no overhead
static assert(Nullable!(size_t, size_t .max) .sizeof == size_t .sizeof);
Example
import std .exception : assertThrown;
Nullable!(int, int .min) a;
assert(a .isNull);
assertThrown!Throwable(a .get);
a = 5;
assert(!a .isNull);
writeln(a); // 5
static assert(a .sizeof == int .sizeof);
Example
auto a = nullable!(int .min)(8);
writeln(a); // 8
a .nullify();
assert(a .isNull);
Authors
Andrei Alexandrescu, Bartosz Milewski, Don Clugston, Shin Fujishiro, Kenji Hara