Assigning to array of structs with custom constructor

Ali Çehreli acehreli at yahoo.com
Tue Apr 26 00:57:54 UTC 2022


On 4/25/22 16:59, Salih Dincer wrote:

 > Because it cannot be used with other possibilities such as
 > ```chunks()``` and ```take()```.

There must be something wrong. map is commonly used with chunks(), 
take(), etc.

 > Also it cannot be customized with
 > ```toString()```.

Can you show examples of these please?

 > I guess even when ```this()``` constructor is added,
 > ```map()``` explodes!

Ah! Now I tried *removing* Bar.this and the compilation failed. Perhaps 
you left the working code in? (?)

For others:

1) Remove Bar.this

2) The code will fail below:

   auto arr2 = "abcdefghi"
              .chunks(3)
              .map!(a => Bar(a))   <-- ERROR
              .array;

Error: cannot implicitly convert expression `a` of type `Take!string` to 
`string`

One confusing thing is the fact that we learn that chunks uses take in 
its implementation. I think it's cool but a newcomer may be confused 
with where that Take comes from. Let's put that aside.

Then the compilation error is easy to understdand because chunks returns 
a range itself but it is not possible to make a Bar from a range. I 
don't agree that this is a problem with map's usability. The type system 
doesn't know what to do.

Here is one way of fixing the issue, not surprisingly, with map itself. ;)

   import std.conv : to;
   auto arr2 = "abcdefghi"
              .chunks(3)
              .map!(c => c.to!string) // <-- ADDED
              .map!(a => Bar(a))
              .array;

Or, one can use a single map expression:

   auto arr2 = "abcdefghi"
              .chunks(3)
              .map!(a => Bar(a.to!string))  // <-- COMBINED
              .array;

Or, a function can be called, etc.

But to remove a misunderstanding, map can be used with most other range 
algorithms, in the standard library, provided by the programmer, etc.

Ali



More information about the Digitalmars-d-learn mailing list