this is not an lvalue
Adam D. Ruppe via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Dec 15 07:29:13 PST 2016
On Thursday, 15 December 2016 at 13:59:05 UTC, Andrey wrote:
> Thanks it works, but where should I use the ref?
Only when you need it, break the habit of using it everywhere.
If it is a value type and you want modifications to the variable
itself be seen outside the function, use it:
void foo(ref int something) {
something++;
}
void main() {
int a = 1;
foo(a);
assert(a == 2);
}
Since int is value and you want to see the change to the local
outside the function, ref is used. However, notice:
void foo(int[] arr) {
arr[0] = 5;
}
void main() {
int[2] a = [1, 2];
foo(a[]);
assert(a[0] == 5);
}
No need for ref there, because the slice is already a reference
to its contents. However, if I wanted to *append* to the slice
and see that length change outside, ref may be appropriate.
This brings me to classes: interfaces and class objects in D are
already automatically pointers internally, just like slices.
void foo(Object o) { /* already like Object* in C++ */
o.modify();
}
void main() {
Object o = new Object();
foo(o);
// o has been modified
}
No need for ref to see changes to the object's internals outside.
However, if you want to rebind the object:
void foo(ref Object o) { /* now like Object** in C++ */
o = new Object();
}
void main() {
Object o;
foo(o);
// o represents the new Object
}
ref is needed there - this is changing the variable itself, not
what is inside it.
With structs, it depends on what you are doing with it - are you
changing the variable itself or something inside it? And what is
inside.
struct Foo {
int a;
}
That Foo acts just like int, so use or don't use ref as if it was
an int.
struct Foo {
int[] a;
}
That one is just like a slice, no need to `ref` that unless you
want to change the outer portion. The contents are implicitly
referenced and not copied.
struct Foo {
int[4] a;
}
Well, this is a value type again, but bigger. Still, I'd say
follow the same rule as plain `int` - only ref that if you need
modifications to be seen outside the function.
struct Foo {
ubyte[1024 * 1024] oneMegabyte;
}
OK, you might want to ref that one just because the copy to the
function may be expensive and the compiler is not necessarily
going to optimize that (BUT the compiler MIGHT optimize it! If
the function gets inlined and it isn't modified, it may compile
to the same thing anyway. Still, I'd probably ref that myself, or
wrap it up in pointers or maybe even a class for its interface.)
General rule of thumb: if you are refing for performance,
actually check it before and after first, ref isn't always faster.
More information about the Digitalmars-d-learn
mailing list