Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
November 05, 2020 Switch between two structs with csvreader | ||||
---|---|---|---|---|
| ||||
Hi There, I am trying to switch between two structs as I am using the csvReader on a raw string. The pseudo-code below throws a "cannot implicitly convert" error due to difference between struct_type1 and struct_type2. I must be doing something wrong or have a wrong understanding of how this function works. Could someone give a good suggestion on handling this? Thanks! Best, Selim auto records = rawtext.csvReader!struct_type1(';'); if(aControlCondition) { records = rawtext.csvReader!struct_type2(';'); } // Iterate through each data row. foreach (record; records) { writeln(record); } |
November 05, 2020 Re: Switch between two structs with csvreader | ||||
---|---|---|---|---|
| ||||
Posted in reply to Selim Ozel | On Thursday, 5 November 2020 at 21:18:52 UTC, Selim Ozel wrote: > auto records = rawtext.csvReader!struct_type1(';'); D is statically typed and `auto` means "deduce this type for me based on this one function's return value". It is not like JavaScript's `var` whose type may change. If I'm not mistaken the `csvReader` function returns a range struct, and the full type is something long and unwieldy like `CsvReader!(struct_type1, cast(Malformed)1, string, dchar, string[])`. So just think of `records` as being that. (You can tell what type it is at compilation with `pragma(msg, typeof(records).stringof)`.) > if(aControlCondition) { > records = rawtext.csvReader!struct_type2(';'); Here `csvReader!struct_type2(';')` returns a value of type `CsvReader!(struct_type2, ...)`, which is a different type from that of `records` (and they're not implicitly convertible). So the error message is right. If `auto` worked like `var` your code would work, but it doesn't. You need two different variables and two different `foreach`es. For the same code to work on both types, the easy solution is templates. Perhaps make the `foreach` part after the reads a templated function that accepts any type passed to it? |
November 06, 2020 Re: Switch between two structs with csvreader | ||||
---|---|---|---|---|
| ||||
Posted in reply to Anonymouse | On Thursday, 5 November 2020 at 22:36:36 UTC, Anonymouse wrote: > If I'm not mistaken the `csvReader` function returns a range struct, and the full type is something long and unwieldy like `CsvReader!(struct_type1, cast(Malformed)1, string, dchar, string[])`. So just think of `records` as being that. I actually first going this route but couldn't figure out the correct name for that data type. It is quite long. > You need two different variables and two different `foreach`es. For the same code to work on both types, the easy solution is templates. Perhaps make the `foreach` part after the reads a templated function that accepts any type passed to it? Embedding the foreach loop inside a template function and deciding on the data type at the higher level function solved my issue. Thanks for the pointer! Best, Selim |
November 06, 2020 Re: Switch between two structs with csvreader | ||||
---|---|---|---|---|
| ||||
Posted in reply to Selim Ozel | On Fri, Nov 06, 2020 at 07:17:53PM +0000, Selim Ozel via Digitalmars-d-learn wrote: > On Thursday, 5 November 2020 at 22:36:36 UTC, Anonymouse wrote: > > If I'm not mistaken the `csvReader` function returns a range struct, and the full type is something long and unwieldy like `CsvReader!(struct_type1, cast(Malformed)1, string, dchar, string[])`. So just think of `records` as being that. > > I actually first going this route but couldn't figure out the correct name for that data type. It is quite long. [...] You can use the typeof() operator to capture the type of a long, unwieldy type in an alias. This is useful if you ever need to store such a return type somewhere, e.g.: alias T = typeof(csvReader(...)); struct MyStorage { T result; } MyStorage s; s.result = csvReader(...); Let the compiler figure out the type for you. :-) T -- Guns don't kill people. Bullets do. |
November 07, 2020 Re: Switch between two structs with csvreader | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Friday, 6 November 2020 at 19:35:47 UTC, H. S. Teoh wrote:
> You can use the typeof() operator to capture the type of a long, unwieldy type in an alias. This is useful if you ever need to store such a return type somewhere, e.g.:
>
> alias T = typeof(csvReader(...));
>
> struct MyStorage {
> T result;
> }
>
> MyStorage s;
> s.result = csvReader(...);
>
> Let the compiler figure out the type for you. :-)
>
>
> T
That's great, thanks!
S
|
Copyright © 1999-2021 by the D Language Foundation