Cannot implicitly convert expression of type const(string[]) to string[]

tsbockman thomas.bockman at gmail.com
Fri Jan 8 23:10:13 UTC 2021


On Friday, 8 January 2021 at 20:43:37 UTC, Andrey wrote:
> Hello,
>
>> struct Value
>> {
>>     int value;
>>     string data;
>>     string[] text;
>> }
>> 
>> void test(const ref Value value)
>> {
>>     Value other = void;
>>     other.text = value.text;
>> }
>> 
>> void main()
>> {
>>     Value row;
>>     row.value = 10;
>>     row.data = "ttttggg";
>> 
>>     test(row);
>> }
>
> I want to pass variable "row" inside function "test" as a read 
> only parameter.
> Inside I create another variable and try to assign field "text".
> On that line I get:
>> Error: cannot implicitly convert expression value.text of type 
>> const(string[]) to string[].
>
> 1. How to assign correctly (and without dup/ugly cast())?
> 2. Or how to pass "row" correctly?

Your code has a logical inconsistency which the compiler has 
rightly detected and flagged for you. You should actually fix the 
inconsistency, not just shut the compiler up.

If the compiler accepted your code, it would be possible to later 
modify the array pointed at by `row.text` through `other.text`, 
because `other.text` is not `const`. This would violate your 
stated desire to pass `row` as read-only.

There are various ways you can fix this, depending on your needs:
     1) Change the type of `other` to `const(Value)` so that 
`other.text` cannot be used to modify `row.text`.
     2) Change the type of `Value.text` to `const(string[])` so 
that it cannot be used to modify `row.text`.
     3) Assign a copy (`dup`) of `row.text` to `other.text` 
instead, so that mutating the array pointed to by `other.text` 
will not modify the original read-only `row`.
     4) Implement a copy-on-write scheme for `Value.text`.
     5) Tell the compiler that `other.text` may be used to mutate 
`row.text` by `const` from the `value` parameter of `test`. Do 
not do this unless that's really what you want!

(1) and (2) are good options, if their limitations happen to fit 
whatever you're really doing. (Note that either requires you to 
write a constructor for `Value` since you won't be able to 
directly write to `Value.text` anymore.)

Unless you are managing huge quantities of data with this `Value` 
type, (3) is a perfectly reasonable thing to do and you shouldn't 
feel guilty about the small "waste" of memory and CPU time for 
the extra allocation. (4) is an option of last resort - not a 
crazy one, but not worth the trouble if the amount of data is 
small relative to system resources and/or the other activities of 
the program.

(5) is simple but WRONG unless you are trying to create multiple 
references to the same mutable data.


More information about the Digitalmars-d-learn mailing list