reassign single elements of a string (using foreach)
Daniel919
Daniel919 at web.de
Thu Jul 5 18:41:11 PDT 2007
Hi, please look at this code (I discuss the problem below):
--------------------------------------------------------------------
import std.stdio;
void main() {
string s = "test";
writefln("s: ", typeid(typeof(s)));
writefln("s[0]: ", typeid(typeof(s[0])));
//(s[0]) = 'a'; //Error: s[0] is not mutable
foreach (ref char c; s) {
writefln("c: ", typeid(typeof(s[0])));
c = 'a';
break;
}
writefln(s);
writefln(typeid(invariant(char[]))); //invariant invariant char[]
writefln(typeid(invariant(char)[])); //invariant char[]
invariant(char)[] f;
writefln(typeid(typeof(f[0]))); //char ????
//what I expected: invariant(char) like:
writefln(typeid(invariant(char))); //invariant char
}
--------------------------------------------------------------------
s: const char[]
s[0]: char
c: char
aest
invariant invariant char[]
invariant char[]
char
invariant char
I can use c (within the foreach) to change elements of the string s.
Exactly: I can assign single values of type char to each element of the
array of invariant chars. (Or I can break after doing so for the n-th
element)
But I can't use s[0] to do the same for exactly one element.
The funny thing is: c and s[0] are of the same type ! Both are char.
Lets take a look at string, which is an alias for invariant(char)[].
What this means: A mutable array of chars (each char can be reassigned,
because of the brackets).
"invariant(char) c;" means: You can assign an other value of type char to c.
(PS: On the docs it should be mentioned, that invariant(builtintype) /
const(builtintype) is useless and behaves like: builtintype)
not to be confused with "invariant char c;" which means: the value of c
will never change and you can't assign an other value to c.
s[0] is of type char, but to make clear, that you can't assign an other
char to it, it should be: "invariant char". Then it would be clear, that
you can't do: s[0] = 'a';
invariant(char[]) -> invariant invariant char[]
| \--------/ |
\------------------/
invariant(char)[] -> invariant char[]
\------/
So one element would mean the [] to be removed, and the rest is:
invariant(char) -> invariant char
But as I pointed out above, this is not the same.
And that's the reason invariant(char) is always translated to: char
Because it behaves as if it was a normal char (also said above), if you do:
invariant(char) c;
You can assign to it, as if it was just: char c:
c = 'a';
Now take exactly one element of a string,
you get an invariant(char) -> char
But you can't assign an other value of type char to it.
So for arrays it's different, although the type is the same (char).
Daniel
More information about the Digitalmars-d
mailing list