Python's list equivalent with std.variant?
jfondren
julian.fondren at gmail.com
Sun Oct 3 23:14:21 UTC 2021
On Sunday, 3 October 2021 at 22:22:48 UTC, rjkilpatrick wrote:
> ```d
> void main() {
> // When we use `SuperClass[] list;` here, we find 'a' is
> hidden by the base class
> Variant[] list;
>
> // Attempting to append derived class instances to list
> list ~= new DerivedClass(1.0f);
> list ~= new OtherDerivedClass;
>
> list[0].a;
> list[0].to!(get!(list[0].type)).a.writeln;
> }
> ```
This works:
```d
void main() {
Variant[] list;
list ~= new DerivedClass(1.0f).Variant;
list ~= new OtherDerivedClass().Variant;
writeln(list[0].get!DerivedClass.a);
}
```
Parameters passed in !() need to be statically known, at
compile-time, so `get!(list[0].type)` doesn't make sense with a
runtime list.
If everything in the list is going to be a child of some class,
then you don't need std.variant at all, you can just use OOP:
```d
import std.stdio : writeln;
class SuperClass {
this() {
}
}
class DerivedClass : SuperClass {
public:
this(float a) {
this.a = a;
}
float a;
}
class OtherDerivedClass : SuperClass {}
class YetAnotherDerivedClass : SuperClass {}
void main() {
SuperClass[] list;
list ~= cast(SuperClass) new DerivedClass(1.0f);
list ~= cast(SuperClass) new OtherDerivedClass;
list ~= cast(SuperClass) new YetAnotherDerivedClass;
writeln((cast(DerivedClass) list[0]).a);
foreach (obj; list) {
if (auto deriv = cast(DerivedClass) obj) {
writeln("I found a DerivedClass: ", deriv.a);
} else if (cast(OtherDerivedClass) obj) {
writeln("I found an OtherDerivedClass");
} else {
writeln("I found an unexpected child: ", obj);
}
}
}
```
output:
```
1
I found a DerivedClass: 1
I found an OtherDerivedClass
I found an unexpected child: variant.YetAnotherDerivedClass
```
Object casts like that are `null` when the cast is invalid.
If you don't necessarily have a superclass, but still do have a
definite number of possible member types, you can use std.sumtype:
```d
import std.stdio : writeln;
import std.sumtype;
struct A { float a; }
struct B { }
struct C { }
alias Alpha = SumType!(A, B, C);
void main() {
Alpha[] list;
list ~= A(1.0f).Alpha;
list ~= B().Alpha;
list ~= C().Alpha;
list[0].tryMatch!((A a) => writeln(a.a));
foreach (obj; list) {
obj.match!(
(A a) => writeln("I found A(", a.a, ")"),
(B _) => writeln("I found B"),
(C _) => writeln("I found C"),
);
}
}
```
output:
```
1
I found A(1)
I found B
I found C
```
More information about the Digitalmars-d-learn
mailing list