www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Static member function returning immutable slice; compiler error:

reply Ivo Maffei <ivomaffei gmail.com> writes:
I'm writing my first D program and I want to have a class which 
contains a private static list of objects.
Moreover such list should be visible from outside the class, so I 
wrote a get method which returns such list as immutable (so that 
the list cannot be modified outside the class).
Finally such method should be static since the list is static and 
therefore I should not need an object to access such list.

Here is the code:

class Foo {
	private static Foo[] fooSlice = new Foo[0]; //private static 
slice

	static immutable Foo[] getFooList() { //static method returning 
an immutable slice
		return fooSlice;
	}	
}

However when compiling with dub I get the following error:

Error: function `main.Foo.getFooList` without this cannot be 
immutable

I noted that the error goes away when I remove the static or 
immutable qualifier.

Thanks a lot for any help.
Jul 05 2018
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 5 July 2018 at 19:43:43 UTC, Ivo Maffei wrote:
 	private static Foo[] fooSlice = new Foo[0]; //private static
That initializer is useless, don't do that, just use the slice.
 	static immutable Foo[] getFooList() { //static method 
 returning an immutable slice
Actually, that's a static immutable *method* returning a mutable slice. It is like you wrote: immutable { // bunch of methods here } so it is applying to this. To make it apply to the return, use parens around it: static immutable(Foo)[] getFooList() {} or static immutable(Foo[]) getFooList() {} the former is a mutable array of immutable objects and the latter is all immutable
Jul 05 2018
prev sibling parent reply ag0aep6g <anonymous example.com> writes:
On 07/05/2018 09:43 PM, Ivo Maffei wrote:
 class Foo {
      private static Foo[] fooSlice = new Foo[0]; //private static slice
 
      static immutable Foo[] getFooList() { //static method returning an 
 immutable slice
          return fooSlice;
      }
 }
 
 However when compiling with dub I get the following error:
 
 Error: function `main.Foo.getFooList` without this cannot be immutable
If you want to return an `immutable Foo[]`, you have to write the signature like this: static immutable(Foo[]) getFooList() Otherwise, the `immutable` qualifier applies to the method itself instead of the `Foo[]` return type. But a static method can't be immutable, so you get the error. But it won't work even if you fix that, because mutable doesn't convert to immutable like that. `immutable` means that the data can't ever change. Not even the owning Foo is allowed to change it. If you want to disallow changes from outside, but still allow the owning Foo to make changes, use `const`: static const(Foo[]) getFooList()
Jul 05 2018
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 07/05/2018 01:00 PM, ag0aep6g wrote:

 `immutable` means that the data can't ever change. Not even the owning
 Foo is allowed to change it. If you want to disallow changes from
 outside, but still allow the owning Foo to make changes, use `const`:

      static const(Foo[]) getFooList()
To add, in that context 'immutable' would be a guarantee to the outside world: "I will never change this data." On the other hand, 'const' means "Dear compiler, please make sure the caller does not mutate this data." However, I think the return type would be more useful as const(Foo)[] to let the caller to be able to add elements to their local copy of the slice: struct Foo { } Foo[] foos; // const(Foo[]) would not allow the concatenation in main. const(Foo)[] getFooList() { return foos; } void main() { auto f = getFooList(); f ~= Foo(); } But then one might argue that if the caller would concatenate anyway, which would cause memory allocation and copying, wouldn't the caller better use .dup to get a mutable copy of the elements. auto f = getFooList().dup; f ~= Foo(); I don't know... Too much analysis... :) Ali
Jul 05 2018
parent Ivo Maffei <ivomaffei gmail.com> writes:
Ok thanks to everyone for their help.

So I tried what you suggested and so the problem was bracketing.

For future reference, the above code can be fixed into this:

class Foo {
	private static Foo[] fooSlice; //private static slice

	static const(Foo[]) getFooList() { //static method returning a 
constant slice
		return fooSlice;
	}	
}
Jul 06 2018