Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
October 29, 2018 anyway to set a const object after the fact? | ||||
---|---|---|---|---|
| ||||
Hi, so if you have this piece of code: struct C { void f() { string[] others; const string[] restArgs; foreach (i, arg; args) { if (isValidArg(arg)) { restArgs = args[i + 1 .. $]; break; } others ~= arg; } // "others" is a list of args before the valid arg is encountered // "restArgs" is a list that is the args after the valid arg } } Is there anyway to set a const object after declaring it in the above context? Cheers, - Ali |
October 29, 2018 Re: anyway to set a const object after the fact? | ||||
---|---|---|---|---|
| ||||
Posted in reply to aliak | On Mon, Oct 29, 2018 at 09:50:32PM +0000, aliak via Digitalmars-d-learn wrote: > Hi, so if you have this piece of code: > > struct C { > > void f() { > string[] others; > const string[] restArgs; > foreach (i, arg; args) { > if (isValidArg(arg)) { > restArgs = args[i + 1 .. $]; > break; > } > others ~= arg; > } > // "others" is a list of args before the valid arg is encountered > // "restArgs" is a list that is the args after the valid arg > } > } > > Is there anyway to set a const object after declaring it in the above context? [...] What exactly are you trying to accomplish? I.e., what semantics do you want from modifying restArgs? If you're looking to rebind the array, just be a bit more explicit in how you spell out the type: const(string)[] restArgs; will allow you to rebind it to a different array / slice, but still not permit you to modify the array elements. T -- Дерево держится корнями, а человек - друзьями. |
October 29, 2018 Re: anyway to set a const object after the fact? | ||||
---|---|---|---|---|
| ||||
Posted in reply to aliak | On Monday, 29 October 2018 at 21:50:32 UTC, aliak wrote:
> Hi, so if you have this piece of code:
>
> struct C {
>
> void f() {
> string[] others;
> const string[] restArgs;
> foreach (i, arg; args) {
> if (isValidArg(arg)) {
> restArgs = args[i + 1 .. $];
> break;
> }
> others ~= arg;
> }
> // "others" is a list of args before the valid arg is encountered
> // "restArgs" is a list that is the args after the valid arg
> }
> }
>
> Is there anyway to set a const object after declaring it in the above context?
>
> Cheers,
> - Ali
Use a lambda:
const string[] restArgs = () {
foreach(i, arg; args) {
if (isValidArg(arg)) {
return args[i+1 .. $];
}
others ~= arg;
}
}();
|
October 30, 2018 Re: anyway to set a const object after the fact? | ||||
---|---|---|---|---|
| ||||
Posted in reply to aliak | On Monday, 29 October 2018 at 21:50:32 UTC, aliak wrote: > Hi, so if you have this piece of code: > > struct C { > > void f() { > string[] others; > const string[] restArgs; > foreach (i, arg; args) { > if (isValidArg(arg)) { > restArgs = args[i + 1 .. $]; > break; > } > others ~= arg; > } > // "others" is a list of args before the valid arg is encountered > // "restArgs" is a list that is the args after the valid arg > } > } > > Is there anyway to set a const object after declaring it in the above context? > > Cheers, > - Ali It looks like there is a Rebindable type for that in std.typecons : https://dlang.org/phobos/std_typecons.html#Rebindable |
October 30, 2018 Re: anyway to set a const object after the fact? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Laurent Tréguier | On Tuesday, 30 October 2018 at 08:18:15 UTC, Laurent Tréguier wrote:
> On Monday, 29 October 2018 at 21:50:32 UTC, aliak wrote:
>> Hi, so if you have this piece of code:
>>
>> struct C {
>>
>> void f() {
>> string[] others;
>> const string[] restArgs;
>> foreach (i, arg; args) {
>> if (isValidArg(arg)) {
>> restArgs = args[i + 1 .. $];
>> break;
>> }
>> others ~= arg;
>> }
>> // "others" is a list of args before the valid arg is encountered
>> // "restArgs" is a list that is the args after the valid arg
>> }
>> }
>>
>> Is there anyway to set a const object after declaring it in the above context?
>>
>> Cheers,
>> - Ali
>
> It looks like there is a Rebindable type for that in std.typecons : https://dlang.org/phobos/std_typecons.html#Rebindable
Guess I could do that. But would there be a difference if I just declared the restArgs as non const then? Given the objective is "set this var to point to this thing and not allow it to be set to point to anything else".
|
October 30, 2018 Re: anyway to set a const object after the fact? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | On Monday, 29 October 2018 at 22:12:24 UTC, Paul Backus wrote:
> Use a lambda:
>
> const string[] restArgs = () {
> foreach(i, arg; args) {
> if (isValidArg(arg)) {
> return args[i+1 .. $];
> }
> others ~= arg;
> }
> }();
That works.
|
October 30, 2018 Re: anyway to set a const object after the fact? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Monday, 29 October 2018 at 22:05:16 UTC, H. S. Teoh wrote: > > What exactly are you trying to accomplish? I.e., what semantics do you want from modifying restArgs? Trying to set restArgs to point to some data but only set it once. Would require some sort of control flow analysis on the part of D though I guess. So meh. > > If you're looking to rebind the array, just be a bit more explicit in how you spell out the type: > > const(string)[] restArgs; > > will allow you to rebind it to a different array / slice, but still not permit you to modify the array elements. > > > T Ya, I was looking to bind once. Like what you can do this with a module constructor: const int a; static this() { a = 5; } |
October 30, 2018 Re: anyway to set a const object after the fact? | ||||
---|---|---|---|---|
| ||||
Posted in reply to aliak | On Tuesday, 30 October 2018 at 11:23:48 UTC, aliak wrote:
> Guess I could do that. But would there be a difference if I just declared the restArgs as non const then? Given the objective is "set this var to point to this thing and not allow it to be set to point to anything else".
The difference with const is that you wouldn't be able to modify the array itself (by adding or removing arguments for example). But yes, you can still re-assign it multiple times using Rebindable, so the lambda solution is a better idea indeed.
|
October 30, 2018 Re: anyway to set a const object after the fact? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Laurent Tréguier | On Tuesday, October 30, 2018 2:18:15 AM MDT Laurent Tréguier via Digitalmars-d-learn wrote:
> On Monday, 29 October 2018 at 21:50:32 UTC, aliak wrote:
> > Hi, so if you have this piece of code:
> >
> > struct C {
> >
> > void f() {
> >
> > string[] others;
> > const string[] restArgs;
> > foreach (i, arg; args) {
> >
> > if (isValidArg(arg)) {
> >
> > restArgs = args[i + 1 .. $];
> > break;
> >
> > }
> > others ~= arg;
> >
> > }
> > // "others" is a list of args before the valid arg is
> >
> > encountered
> >
> > // "restArgs" is a list that is the args after the valid arg
> >
> > }
> >
> > }
> >
> > Is there anyway to set a const object after declaring it in the above context?
> >
> > Cheers,
> > - Ali
>
> It looks like there is a Rebindable type for that in std.typecons
>
> : https://dlang.org/phobos/std_typecons.html#Rebindable
Rebindable is specifically intentended for class references, since D doesn't really distinguish between the reference and what it's pointing to, making it impossible to under normal circumstances to have a mutable reference to a const object. On the other hand, you can easily have mutable arrays of const objects. Using Rebindable is a really a hack (albeit a very necessary one for some circumstances), and I would very much advise _against_ using it if you don't need it. Historically, it tends to run into compiler bugs, because it's trying to hack it's way around the type system, and if you're not dealing with class references, there's probably a better way to handle the problem.
- Jonathan M Davis
|
Copyright © 1999-2021 by the D Language Foundation