Thread overview | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 14, 2020 Casting by assigning to the right ... | ||||
---|---|---|---|---|
| ||||
... is already builtin via properties. After declaring ``` struct S{ int data;} S s; int i; ``` one often would like to implicitly cast the value of the structure by typing ``` i= s; ``` According to the logged changes ( https://digitalmars.com/d/2.0/changelog.html) a thought on this was published in 2008/03 for D2.012: `opImplicitCast', but not implemented since. Therefore one still has to introduce an `opCast' into `S' and then write ``` i= cast( int) s; ``` I do not like to always correctly examine the type of the variable I am assigning to ( `i' in this case) for using that type in the `cast()' and came up with the idea to no more assign to the left but to the right: ``` s.castTo =i; ``` Of course one has to define the property `castTo' within `S', but that has the signature `void castTo( ref int arg)' which is as simple as the signature of `opCast'. A runnable example follows. What do you think? ``` struct S{ string data; int opCast( T: int)(){ import std.conv: to; return to!int( data); } void castTo( ref int arg){ arg= cast( int) this; } } void main(){ auto s= S( "42"); int i; s.castTo =i; import std.stdio; writeln( i); } ``` |
April 14, 2020 Re: Casting by assigning to the right ... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manfred Nowak | On 4/14/20 1:56 AM, Manfred Nowak wrote:
> According to the logged changes ( https://digitalmars.com/d/2.0/changelog.html) a thought on this was published in 2008/03 for D2.012: `opImplicitCast', but not implemented since.
The feature was implemented in a way, it's called alias this:
struct S
{
int i;
alias i this;
}
auto s = S(5);
int i = s;
assert(i == 5);
Note that at this time, only one alias this is allowed per structure.
-Steve
|
April 14, 2020 Re: Casting by assigning to the right ... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manfred Nowak | On Tuesday, 14 April 2020 at 05:56:39 UTC, Manfred Nowak wrote:
> ... is already builtin via properties.
>
> After declaring
> ```
> struct S{ int data;}
> S s;
> int i;
> ```
>
> one often would like to implicitly cast the value of the structure by typing
> ```
> i= s;
> ```
There's two easy ways to accomplish this:
```
struct S
{
int data_;
version (OpAssign) ref S opAssign (int v) { this.data_ = v; return this; }
version (AliasThis)
{
@property ref int data (int v) { this.data_ = v; return this.data_; }
alias data this;
}
}
void main ()
{
S s;
int i;
s = i;
}
```
Which one you pick depends on your design. I would recommend the `OpAssign` version by default.
|
April 14, 2020 Re: Casting by assigning to the right ... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Tuesday, 14 April 2020 at 06:10:33 UTC, Steven Schveighoffer wrote:
> Note that at this time, only one alias this is allowed per structure.
This restriction falls by the suggested scheme:
```
struct S{
string data;
import std.conv: to;
void castTo( ref int arg){
arg= to!int( data);
}
void castTo( ref string arg){
arg= data;
}
}
void main(){
auto s= S( "42");
int i;
s.castTo =i;
string str;
s.castTo =str;
import std.stdio;
writeln( i, ":", str); // 42:42
}
```
|
April 14, 2020 Re: Casting by assigning to the right ... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mathias LANG | On Tuesday, 14 April 2020 at 06:15:14 UTC, Mathias LANG wrote: [...] > ref S opAssign (int v) { this.data_ = v; return this; } [...] > s = i; With `opAssign' the value of `i' is assigned to `this.data_', but that is not the intended direction. From `this.data_' to `i' is intended ... and for several more types of variables. Please see my reply to Steven: https://forum.dlang.org/post/qdzvuduycklkhjesnyei@forum.dlang.org |
April 14, 2020 Re: Casting by assigning to the right ... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manfred Nowak | On 4/14/20 2:44 AM, Manfred Nowak wrote:
> On Tuesday, 14 April 2020 at 06:10:33 UTC, Steven Schveighoffer wrote:
>> Note that at this time, only one alias this is allowed per structure.
>
> This restriction falls by the suggested scheme:
>
> ```
> struct S{
> string data;
> import std.conv: to;
> void castTo( ref int arg){
> arg= to!int( data);
> }
> void castTo( ref string arg){
> arg= data;
> }
> }
> void main(){
> auto s= S( "42");
>
> int i;
> s.castTo =i;
>
> string str;
> s.castTo =str;
>
> import std.stdio;
> writeln( i, ":", str); // 42:42
> }
> ```
Yes, I was responding to the point talking about opImplicitCast. Instead of that, we got alias this.
Proposals have been started to add multiple alias this. I think many consider alias this in general to be a troublesome feature that could have been done better. I don't know what will happen with it.
I would recommend not using the = syntax to denote the opposite of what it normally means (that the rhs is being assigned). You are better off I think just calling it like a function:
s.castTo(i);
s.castTo(str);
Without knowing what castTo is supposed to do, if I saw s.castTo = i, I would not expect at all that i is going to change.
-Steve
|
April 14, 2020 Re: Casting by assigning to the right ... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manfred Nowak | On Tuesday, 14 April 2020 at 05:56:39 UTC, Manfred Nowak wrote:
> ... is already builtin via properties.
>
> After declaring
> ```
> struct S{ int data;}
> S s;
> int i;
> ```
>
> one often would like to implicitly cast the value of the structure by typing
> ```
> i= s;
> ```
>
> According to the logged changes ( https://digitalmars.com/d/2.0/changelog.html) a thought on this was published in 2008/03 for D2.012: `opImplicitCast', but not implemented since.
>
> Therefore one still has to introduce an `opCast' into `S' and then write
> ```
> i= cast( int) s;
> ```
>
> I do not like to always correctly examine the type of the variable I am assigning to ( `i' in this case) for using that type in the `cast()' and came up with the idea to no more assign to the left but to the right:
> ```
> s.castTo =i;
> ```
>
> Of course one has to define the property `castTo' within `S', but that has the signature
> `void castTo( ref int arg)'
> which is as simple as the signature of `opCast'. A runnable example follows. What do you think?
>
>
> ```
> struct S{
> string data;
> int opCast( T: int)(){
> import std.conv: to;
> return to!int( data);
> }
> void castTo( ref int arg){
> arg= cast( int) this;
> }
> }
> void main(){
> auto s= S( "42");
> int i;
> s.castTo =i;
> import std.stdio;
> writeln( i);
> }
> ```
Always a fan of generalizing patterns as long as they are readable! So I would agree with Steven that
s.castTo = i
would be a bit confusing to review. And:
s.castTo(i);
would also be confusing in that it sounds like it's casting s to i as in, turning s in to an i. But it's hard to know what that can actually mean.
Also, you can make it a generic free function if you want. I.e. turn this:
struct S {
void castTo( ref int arg){
arg= cast( int) this;
}
}
to:
void castTo(Source, Dest)(ref Source source, ref Dest dest) {
dest = cast(Dest)source;
}
And now you can have your i on the left hand side and maybe name it something like castAssign and have code that reads like
i.castAssign(s); // cast and assign s
|
April 14, 2020 Re: Casting by assigning to the right ... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manfred Nowak | On Tuesday, 14 April 2020 at 05:56:39 UTC, Manfred Nowak wrote:
> ```
> i= cast( int) s;
> ```
>
> I do not like to always correctly examine the type of the variable I am assigning to ( `i' in this case) for using that type in the `cast()' and came up with the idea to no more assign to the left but to the right:
You can avoid the need to look up the type by using `typeof`:
i = cast(typeof(i)) s;
|
April 14, 2020 Re: Casting by assigning to the right ... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | On Tuesday, 14 April 2020 at 14:50:29 UTC, Paul Backus wrote:
> You can avoid the need to look up the type by using `typeof`:
>
> i = cast(typeof(i)) s;
Yes. But it is unnecessary bloat of about 15 chars. I would rather annotate my knowledge of implicit-cast-assigning by writing:
`i:= s;'
|
April 14, 2020 Re: Casting by assigning to the right ... | ||||
---|---|---|---|---|
| ||||
Posted in reply to aliak | On Tuesday, 14 April 2020 at 13:03:19 UTC, aliak wrote: > Also, you can make it a generic free function if you want. [...] > i.castAssign(s); // cast and assign s And because the pair of parenthesis can by exchanged by a `=', giving `i .castAssign= s;' you just evaluated, that there is in addition to {+, -, *, /, %, ^^, &, |, ^, <<, >>, >>>, ~} an additional bunch of ops for the op-assignment-operator giving the resulting form in regular language parlor: '.' ident '=' Allowing ident to be an empty string would even include `.=' to be recognized as an assignment operator. This is very close to the assignment operator in pascal `:='. What is the better annotation of a coder knowing, that a cast is being executed under the hood: `._=' or `:='? |
Copyright © 1999-2021 by the D Language Foundation