On Wednesday, February 22, 2012 03:07:38 ixid wrote:
> BLM:
> const(char)[][] words = set.keys.sort;
> 
> Converting the function's return type to const and doing this did
> what I wanted elegantly, I didn't realise I could apply sort to a
> const like this.
> 
> Trying to use .dup like this:
> 
> char[][] words = set.keys.dup;
> 
> gives this error message:
> 
> Error: cannot implicitly convert expression (_adSort(_adDupT(&
> D13TypeInfo_AAxa6__initZ,set.keys()),& D11TypeInfo_Aa6__initZ))
> of type const(char)[][] to char[][]
> 
> Isn't there any sort of cast(nonconst) equivalent?

1. Don't use the built-in sort. It's going to be deprecated. Use 
std.algorithm.sort.

2. You should pretty much _never_ cast away const or immutable in D unless you 
really know what you're doing. Casting away const or immutable and then 
modifying a variable is undefined (unlike in C++). It violates the compiler's 
guarantees and risks segfaulting and the like.

> char[][] words;
> words.length = set.keys.length;
> foreach(size_t i, const char[] text; set.keys) {
> words[i] = text.dup;
> }
> 
> This also worked, thank you for the suggestion.
> 
> Jonathan M Davies:
> >bool[char[]] set;
> >
> >doesn't work, because the key isn't immutable. When he tries to
> >use it the compiler will scream at him (though ideally, it
> >wouldn't even let him declare it - there's a bug report on that).
> 
> When I use a key with it I use:
> 
> set[cast(immutable) key] = true;
> 
> This doesn't generate any compiler errors.
> 
> auto words2 = set.keys.sort;
> auto words2 = set.keys.dup.sort;


_Don't_ cast to immutable unless you can _guarantee_ that there are no other 
references to the variable being cast. You're going to get bugs otherwise. In 
general, if you're doing any casts to or from const or immutable, you're doing 
something wrong (there are exceptions - primarily involving passing stuff 
across threads - but again, you have to know what you're doing).

If the key is not already immutable (or has immutable elements in the case of 
an array), then you need to actually get an immutable version, not cast it. In 
the case of an array, that would mean using idup. However, even better would 
be to use std.conv.to. That way, if the array or its elements are already 
immutable, you don't end up needlessly copying the array.

For instance,

bool[string] set;
set[to!string(key)] = value;

> both did what I wanted using string. Thank you, I'll convert
> everything to strings. I guess I created my own difficulties by
> using char arrays.

Yes. In general, you should be using string (which is immutable(char)[]) 
rather than char[]. In general, modifying an array of char just doesn't make 
sense (particularly in light of unicode), and you'll generally run into fewer 
difficulties. It also helps avoid duplication, because you never need to copy 
arrays of immutable elements unless you need a mutable copy, whereas you tend 
to have to copy arrays of mutable elements to avoid having stuff modify them. 
Also, more functions in the standard library support string than char[].

This question on stackoverflow would be good to look at for a more detailed 
explanation with regards to AAs and immutability:

http://stackoverflow.com/questions/4611477/why-cant-i-store-string-keys-in-an-
associative-array

Also, if you haven't read it yet, you should read this article on arrays:

http://www.dsource.org/projects/dcollections/wiki/ArrayArticle

It should help you understand how they work, which will hopefully help you 
avoid some headaches.

- Jonathan M Davis

Reply via email to