How to make a function that accepts optional struct but can accept struct literal too

jfondren julian.fondren at gmail.com
Fri Oct 15 21:19:35 UTC 2021


On Friday, 15 October 2021 at 20:33:33 UTC, JN wrote:
> Is there some nice way of achieving something like this C99 
> code in D?

option 1: use an intermediate lambda:

```d
import std.stdio;

struct inputs_t {
     int x, y;
} // no ; needed here

void foo(inputs_t* optional_inputs) {
     if (!optional_inputs) {
         writeln("0 0");
     } else {
         writeln(optional_inputs.x, " ", optional_inputs.y);
     }
}

void main() {
     import std.functional : pipe;

     foo(null); // prints 0 0
     inputs_t(5, 6).pipe!(s => foo(&s)); // prints 5 6
}
```

option 2: use a class

```d
class inputs_t {
     int x, y;
     this(int x, int y) {
         this.x = x;
         this.y = y;
     }
}

void foo(inputs_t optional_inputs) {
     import std.stdio : writeln;

     if (!optional_inputs) {
         writeln("0 0");
     } else {
         writeln(optional_inputs.x, " ", optional_inputs.y);
     }
}

void main() {
     foo(null);
     foo(new inputs_t(5, 6));
}
```

option 3: use std.sumtype

```d
import std.sumtype;

struct Point {
     int x, y;
}

alias Input = SumType!(Point, typeof(null));

void foo(Input inputs) {
     import std.stdio : writeln;

     inputs.match!(
         (typeof(null) _) => writeln("0 0"),
         (Point p) => writeln(p.x, " ", p.y),
     );
}

void main() {
     foo(null.Input);
     foo(Point(5, 6).Input);
}
```

option 4: use overloading

```d
import std.stdio : writeln;

struct Point {
     int x, y;
}

void foo() {
     writeln("0 0");
}
void foo(Point p) {
     writeln(p.x, " ", p.y);
}

void main() {
     foo();
     foo(Point(5, 6));
}
```

option 5: use S.init, when your exceptional value is handled the 
same

```d
struct Point {
     int x, y;
}

void foo(Point p = Point.init) {
     import std.stdio : writeln;

     writeln(p.x, " ", p.y);
}

void main() {
     foo();            // 0 0
     foo(Point.init);  // 0 0
     foo(Point(5, 6)); // 5 6
}
```


More information about the Digitalmars-d-learn mailing list