On Thursday, 3 October 2019 at 04:32:52 UTC, Brett wrote:
struct Y { double q; }
struct X { Y[] a; }

X x;

auto r = x.a;

r is not a reference?!?!

Arrays are (ptr,length) pairs. r is a copy of them:

  #! /usr/bin/env rdmd
  import std.stdio;

  struct X { int[] a; }

  void main() {
      auto test = X([0]);
      test.a.reserve(10); // for later
      auto r = test.a;
      writeln(test.a.ptr == r.ptr); // true
      writeln(test.a.length == r.length); // true
  }

Mutate it and they're still using the same ptr:

      r ~= [1];
      writeln(test.a.ptr == r.ptr); // true
      writeln(test.a.length == r.length); // false

But r is still a copy of the ptr,length pair, and
its length is updated separately.

Consider:

  #! /usr/bin/env rdmd
  import std.stdio;

  struct X { int[] a; }

  void main() {
      X test;
      test.a.reserve(3);
      auto a = test.a;
      a ~= [1, 2, 3];
      auto r = test.a.ptr[0..3];
      writeln(r); // output: [1, 2, 3]
  }

I have to slice the ptr directly as array operations are aware
of all this. Consider:

  #! /usr/bin/env rdmd
  import std.stdio;

  struct X { int[] a; }

  void main() {
      X test;
      test.a.reserve(3);
      auto a = test.a;
      a ~= [1, 2, 3];
      test.a.length = 3;
      writeln(test.a); // [0,0,0]
      writeln(a); // [1,2,3]
  }

What you can do copy the (ptr,length) pair, do what you want with
it, and then assign it back to the struct. Don't worry about tricky
stuff.

auto r = &x.a;

Now r is a reference, great!.

look at it:

    writeln(typeid(a)); // output: int[]*

It's a pointer to an int[]. It behaves like a pointer.

I want to have a slice of an array that I can append to as a sort of temporary and have it append to the main array(the end of the slice always is the end of the main array)..

I've tried assumeSafeAppend but it does nothing to help.

Learning D goes into tons of detail about slices and appending to
copies and when you'd want assumeSafeAppend and so on.

Reply via email to