D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3814 - Mutation of immutable string
Summary: Mutation of immutable string
Status: RESOLVED INVALID
Alias: None
Product: D
Classification: Unclassified
Component: druntime (show other issues)
Version: D2
Hardware: x86 Windows
: P2 normal
Assignee: Sean Kelly
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-02-18 09:51 UTC by bearophile_hugs
Modified: 2015-06-09 01:27 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2010-02-18 09:51:03 UTC
import std.stdio: writeln;
void main() {
    string s = "ab";
    s.length += 1;
    //writeln(typeid(typeof(s))); // Prints:
    s[2] = 'a'; // test5.d(6): Error: s[2] isn't mutable
}

Why is length+=1 allowed if s is immutable?
Comment 1 Steven Schveighoffer 2010-02-18 10:33:46 UTC
s is not immutable, only the data it points to.

s is of type immutable(char)[], which means the array itself can be added to or reassigned to another slice of data, but the data it points to is immutable.  It is read "an array of immutable chars" instead of "an immutable array of chars".

If you want an immutable string, do:

immutable string s = "ab";

Which you will not be able to change the length of.

Also could do:

immutable char[] s = "ab";
Comment 2 bearophile_hugs 2010-02-18 10:59:18 UTC
A string can't be defined immutable (and can't enjoy the advantages of immutability, like being a safer hash key) if it can change size. This is a half-immutability of strings. Maybe there is no good solution to this...
Comment 3 Steven Schveighoffer 2010-02-18 11:23:09 UTC
It does have immutable traits.  With D's immutable strings, the *shared* part is immutable.  That is, you can share strings because of the hybrid value/reference type that is an array (shared data, local length).  It's a very different concept to other programming languages.

Because strings are not true reference types, changing the length of one string does not affect another string, even if both point to the same data.

Think about how Java has immutable strings, but you can reassign a string variable.  That does not make the strings themselves not immutable!  However, immutable strings in Java are pure reference types (even the length is shared), so in order to take a "slice" of a string, you must make an entirely new object, but the same data (except for the length) is referenced.  The same is not true in D where the string length is not shared, and therefore does not need to be immutable.