Is std.variant useful for types only known at run time?
jfondren
julian.fondren at gmail.com
Wed Sep 8 08:39:53 UTC 2021
On Wednesday, 8 September 2021 at 07:10:21 UTC, Chris Piker wrote:
> Hi D
>
> I'm working on data streaming reading module where the encoding
> of each input array isn't known until runtime. For example
> date-time column values may be encoded as:
>
> * An ISO-8601 UTC time string (aka char[])
> * A ASCII floating point value with an indicated unit size
> and epoch (aka char[])
> * A IEEE double with an indicated endianness, unit size, and
> epoch. (aka double[])
> * A 64-bit signed in with an indicated endianness, unit
> size, and epoch. (aka long[])
a std.variant.Variant can contain *any* type, but this only four
types, so I'd look at a std.sumtype of them first:
```d
import std.sumtype;
struct ISO8601 { }
struct FloatEpoch { }
struct DoubleEpoch { }
struct LongEpoch { }
alias Time = SumType!(ISO8601, FloatEpoch, DoubleEpoch,
LongEpoch);
void main() {
import std.stdio : writeln;
import std.format : format;
Time e = ISO8601();
writeln(e.match!(
(FloatEpoch _) => "doesn't happen",
(DoubleEpoch _) => "doesn't happen",
(LongEpoch _) => "an error to omit, unlike the next
example",
(ISO8601 time) => format!"%s"(time),
));
}
```
...
> I'm wondering if std.variant is useful in cases where type
> information is only known at run-time, since many of the
> flexible data structures I've run across so far in D require
> compile-time information.
It is. It's used for message passing in std.concurrency for
example, where an actor can receive any kind of type into its
messagebox. If std.sumtype didn't exist then I might look at
std.variant or a novel discriminated union of my own or OOP,
where an option is to try casting to the different subtypes until
the cast works:
```d
class Encoding { }
class ISO8601 : Encoding { }
class FloatEpoch : Encoding { }
class DoubleEpoch : Encoding { }
class LongEpoch : Encoding { }
void main() {
import std.stdio : writeln;
Encoding e = new ISO8601;
if (!cast(FloatEpoch) e) writeln("it's null");
if (!cast(LongEpoch) e) writeln("it's null");
if (auto time = cast(ISO8601) e)
writeln(time);
}
```
More information about the Digitalmars-d-learn
mailing list