Thread overview | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 15, 2006 back to arays | ||||
---|---|---|---|---|
| ||||
I thought array references are similar to object references like in C# (actually, thay are object references in C#) and that was my mistake: int[] a = new int[20]; int[] b = a; a.length = 40; // a is copied and b is not updated to point to a's data; Does it mean that anytime i change an array, i have to manually update all references to it or should i wrap my array in an Array class so that all references to any instance of that array remain valid? If the question have been already discussed please refer me to the right thread. Thanks |
May 15, 2006 Re: back to arays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Max Samuha | On Mon, 15 May 2006 10:05:22 +0300, Max Samuha <maxter@i.com.ua_spamless> wrote:
> I thought array references are similar to object references like in C#
> (actually, thay are object references in C#) and that was my mistake:
>
> int[] a = new int[20];
> int[] b = a;
>
> a.length = 40; // a is copied and b is not updated to point to a's
> data;
>
> Does it mean that anytime i change an array, i have to manually update
> all references to it or should i wrap my array in an Array class so
> that all references to any instance of that array remain valid?
>
> If the question have been already discussed please refer me to the
> right thread. Thanks
The D philosophy is "copy on write". Whenever you have several references to the same data and you decide to write to the data, you should make a copy and write to the copy. If you want to constantly have several references to the same data then yes, you will have to update the references whenever you make change or write a class to handle that for you.
Regan
|
May 15, 2006 Re: back to arays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Max Samuha | On Mon, 15 May 2006 10:05:22 +0300, Max Samuha wrote: > I thought array references are similar to object references like in C# (actually, thay are object references in C#) and that was my mistake: > > int[] a = new int[20]; > int[] b = a; > > a.length = 40; // a is copied and b is not updated to point to a's data; > > Does it mean that anytime i change an array, i have to manually update all references to it or should i wrap my array in an Array class so that all references to any instance of that array remain valid? > > If the question have been already discussed please refer me to the right thread. Thanks I assume for some valid reason you want this behaviour... int[] a = new int[20]; int[] b = a; int[] c = a; a[0] = 17; writefln("%s %s", b[0], c[0]); // Displays 17 17 The simplest way to do this is ... int[] a = new int[20]; int[]* b = &a; int[]* c = &a; a[0] = 17; writefln("%s %s", b[0], c[0]); // Displays 17 17 I'm not sure why one would need this behaviour though. Why do you need two identifiers in the same scope to reference the same data? -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 15/05/2006 5:49:08 PM |
May 15, 2006 Re: back to arays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Max Samuha | Max Samuha skrev:
> I thought array references are similar to object references like in C#
> (actually, thay are object references in C#) and that was my mistake:
>
> int[] a = new int[20];
> int[] b = a;
>
> a.length = 40; // a is copied and b is not updated to point to a's
> data;
>
> Does it mean that anytime i change an array, i have to manually update
> all references to it or should i wrap my array in an Array class so
> that all references to any instance of that array remain valid?
>
> If the question have been already discussed please refer me to the
> right thread. Thanks
The behavior of D's built in arrays have been the cause of much confusion.
D's arrays actually have a kind of schizophrenic nature. They are value types referring to some portion of memory, and as such, they are not pure arrays (of course a matter of interpretation), but rather array slices. On the other hand they support append operations, and automatically copy and reallocate the data when the length is increased, which doesn't make sense for a pure slice type.
So in the sense of being arrays, D's arrays neither fulfill the expected semantics of being a value type nor a reference type.
This will probably make many D users cringe, by my suggestion is to use an array wrapper type with reference semantics. Something like this: (untested and incomplete code)
class Array(T) {
T[] data;
this() {}
this(int n) { length(n); }
this(T[] data) { this.data = data; }
void length(size_t n) { data.length = n; }
size_t length() { return data.length; }
Array dup() { return new Array(data.dup); }
T opIndex(size_t i) { return data[i]; }
T opIndexAssign(T v, size_t i) { return data[i] = v; }
T[] opSlice(size_t a, size_t b) { return data[a..b]; }
int opApply(...) {...}
}
Usage:
Array!(int) a = new Array!(int)(20);
Array!(int) b = a;
a.length = 40; // a is NOT copied and b is updated to point to a's data
Properly implemented this will work as you expect with one caveat. There is no reference return type for opIndex, making arrays of structs somewhat inconvenient.
I think you can find a proper implementation in the ancient DTL library.
Regards,
Oskar
|
May 15, 2006 Re: back to arays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote: > On Mon, 15 May 2006 10:05:22 +0300, Max Samuha wrote: > >> I thought array references are similar to object references like in C# >> (actually, thay are object references in C#) and that was my mistake: >> >> int[] a = new int[20]; >> int[] b = a; >> >> a.length = 40; // a is copied and b is not updated to point to a's >> data; >> >> Does it mean that anytime i change an array, i have to manually update >> all references to it or should i wrap my array in an Array class so >> that all references to any instance of that array remain valid? >> >> If the question have been already discussed please refer me to the >> right thread. Thanks > > I assume for some valid reason you want this behaviour... > > int[] a = new int[20]; > int[] b = a; > int[] c = a; > a[0] = 17; > writefln("%s %s", b[0], c[0]); // Displays 17 17 But... it will display '17 17'. > The simplest way to do this is ... > > int[] a = new int[20]; > int[]* b = &a; > int[]* c = &a; > a[0] = 17; > writefln("%s %s", b[0], c[0]); // Displays 17 17 Nope, the earlier one :) As I understand it, he'd like this code: # int[] a = new int[20]; # int[] b = a; # b.length = 10; # writefln("%s %s", a.length, b.length); to output '20 20'. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d-pu s+: a-->----- C+++$>++++ UL P+ L+ E--- W++ N++ o? K? w++ !O !M V? PS- PE- Y PGP t 5 X? R tv-- b DI- D+ G e>+++ h>++ !r !y ------END GEEK CODE BLOCK------ Tomasz Stachowiak /+ a.k.a. h3r3tic +/ |
May 15, 2006 Re: back to arays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tom S | On Mon, 15 May 2006 20:24:39 +1000, Tom S <h3r3tic@remove.mat.uni.torun.pl> wrote: > Derek Parnell wrote: >> On Mon, 15 May 2006 10:05:22 +0300, Max Samuha wrote: >> >>> I thought array references are similar to object references like in C# >>> (actually, thay are object references in C#) and that was my mistake: >>> >>> int[] a = new int[20]; >>> int[] b = a; >>> >>> a.length = 40; // a is copied and b is not updated to point to a's >>> data; >>> >>> Does it mean that anytime i change an array, i have to manually update >>> all references to it or should i wrap my array in an Array class so >>> that all references to any instance of that array remain valid? >>> >>> If the question have been already discussed please refer me to the >>> right thread. Thanks >> I assume for some valid reason you want this behaviour... >> int[] a = new int[20]; >> int[] b = a; >> int[] c = a; >> a[0] = 17; >> writefln("%s %s", b[0], c[0]); // Displays 17 17 > > But... it will display '17 17'. > > >> The simplest way to do this is ... >> int[] a = new int[20]; >> int[]* b = &a; >> int[]* c = &a; >> a[0] = 17; >> writefln("%s %s", b[0], c[0]); // Displays 17 17 > > Nope, the earlier one :) > > > As I understand it, he'd like this code: > > # int[] a = new int[20]; > # int[] b = a; > # b.length = 10; > # writefln("%s %s", a.length, b.length); > > to output '20 20'. That's what you get while trying to rush out of the office, late again for dinner. You are right. Here is my improved attempt and what I was trying to say earlier... import std.stdio; void main() { int[] a; int[]* b; int[]* c; b = &a; c = &a; a.length= 40; a[0] = 17; writefln("%d %d", c.length, b.length); writefln("%d %d", *c[0], *b[0]); } ------------------------- This displays 40 40 17 17 ------------------------- But I still don't know why one would want to do this? -- Derek Parnell Melbourne, Australia |
May 15, 2006 Re: back to arays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tom S | Tom S wrote: > > > As I understand it, he'd like this code: > > # int[] a = new int[20]; > # int[] b = a; > # b.length = 10; > # writefln("%s %s", a.length, b.length); > > to output '20 20'. > > You mean "to output '10 10'", no? -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D |
May 15, 2006 Re: back to arays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote: > I'm not sure why one would need this behaviour though. Why do you need two > identifiers in the same scope to reference the same data? > Derek Parnell wrote: > > But I still don't know why one would want to do this? > I'll bet the identifiers are on the same scope just for simplification purposes. The case were you would want to have a dyn array to behave "wholly" like a reference type is quite common and necessary, just like associative arrays are now "wholly" a reference type. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D |
May 15, 2006 Re: back to arays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bruno Medeiros | Bruno Medeiros wrote: > You mean "to output '10 10'", no? Arrrgh you're right :S -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d-pu s+: a-->----- C+++$>++++ UL P+ L+ E--- W++ N++ o? K? w++ !O !M V? PS- PE- Y PGP t 5 X? R tv-- b DI- D+ G e>+++ h>++ !r !y ------END GEEK CODE BLOCK------ Tomasz Stachowiak /+ a.k.a. h3r3tic +/ |
May 15, 2006 Re: back to arays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Max Samuha | You can always "cheat" and do:
alias a b;
Max Samuha wrote:
> I thought array references are similar to object references like in C#
> (actually, thay are object references in C#) and that was my mistake:
>
> int[] a = new int[20];
> int[] b = a;
>
> a.length = 40; // a is copied and b is not updated to point to a's
> data;
>
> Does it mean that anytime i change an array, i have to manually update
> all references to it or should i wrap my array in an Array class so
> that all references to any instance of that array remain valid?
>
> If the question have been already discussed please refer me to the
> right thread. Thanks
|
Copyright © 1999-2021 by the D Language Foundation