On Thursday, 10 April 2014 at 10:47:08 UTC, Rene Zwanenburg wrote:
On Thursday, 10 April 2014 at 10:16:43 UTC, Chris wrote:
Ah, this one \me (= escaped me). Sorry I wasn't precise, I was wondering if it is in any way dangerous to have

@property string[] items() {
 return buf.data;
}

instead of:

string[] items;
// ...
public addItem(string item) {
 items ~= item;
}

because the two are not the same. When you print MyStruct to console you get the address of appender buf, whereas when you use string[] items you get the actual items. I'm only wondereing if using appender is potentially dangerous and could bite me later.

The only thing I know of is if you store the reference returned by items(), clear the appender, and add new items, the contents of the previously returned slice will change too. Clearing an appender is similar to setting slice length to 0 and calling assumeSafeAppend on it.

Like so:

import std.stdio, std.array;

void main() {
  auto mystr1 = MyStruct1("Hello1");
  auto mystr2 = MyStruct2("Hello2");
  mystr1.addItem("World1");
  mystr2.addItem("World2");
  auto data1 = mystr1.items;
  writeln(mystr1.buf.data.length);
  auto data2 = mystr2.items;
  writeln(data1[0]);
  writeln(data2[0]);
  mystr1.clear();
  mystr2.clear();
  writeln(mystr1.buf.data.length);
  writeln(data1[0]);
  writeln(data2[0]);
  mystr1.addItem("After World 1");
  mystr2.addItem("After World 2");
  writeln(mystr1.items[0]);
  writeln(mystr2.items[0]);
  writeln(data1[0]);  // Is now After World 1
  writeln(data2[0]);  // Still is World2
}

struct MyStruct1 {
  Appender!(string[]) buf;
  string name;

  this(string name) {
    this.name = name;
    buf = appender!(string[]);
  }

  public void addItem(string item) {
    buf.put(item);
  }

  @property ref auto items() {
    return buf.data;
  }

  public void clear() {
    buf.clear();
  }
}

struct MyStruct2 {
  string[] stuff;
  string name;

  this(string name) {
    this.name = name;
  }

  public void addItem(string item) {
    stuff ~= item;
  }

  @property ref string[] items() {
    return stuff;
  }

  public void clear() {
    stuff.clear();
  }
}

Reply via email to