Design with appender: good or bad?
Chris
wendlec at tcd.ie
Thu Apr 10 06:57:25 PDT 2014
On Thursday, 10 April 2014 at 13:53:46 UTC, Chris wrote:
> 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();
> }
> }
The funny thing, though, is that after clearing buf
writeln(data1[0]);
still prints "World1". It only changes after I add a new item to
buf.
More information about the Digitalmars-d-learn
mailing list