Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
June 11, 2011 char[] to string | ||||
---|---|---|---|---|
| ||||
Why doesn't this work? import std.stdio; string copy_string(char [] input) { return input.dup; } int main() { char [] buf = ['h', 'e', 'l', 'l', 'o']; writeln( copy_string(buf) ); } I want to do something more complex. In my code, I want to have a dynamic array that I can append stuff into and then return it as a string. In C++, a non-const variable can be implicitly converted into a const. I know string is an alias for const char. Is there a reason why it won't implicitly convert it? I hesitate to use cast for this type of thing as it probably indicates I'm doing something fundamentally wrong as I'm just starting to learn the language. |
June 11, 2011 Re: char[] to string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan Sternberg | On 2011-06-10 19:56, Jonathan Sternberg wrote:
> Why doesn't this work?
>
> import std.stdio;
>
> string copy_string(char [] input)
> {
> return input.dup;
> }
>
> int main()
> {
> char [] buf = ['h', 'e', 'l', 'l', 'o'];
> writeln( copy_string(buf) );
> }
>
> I want to do something more complex. In my code, I want to have a dynamic array that I can append stuff into and then return it as a string. In C++, a non-const variable can be implicitly converted into a const. I know string is an alias for const char. Is there a reason why it won't implicitly convert it?
>
> I hesitate to use cast for this type of thing as it probably indicates I'm doing something fundamentally wrong as I'm just starting to learn the language.
string is an alias for immutable(char)[]. The elements of a string can never be altered. dup returns a mutable copy of a string (not const, not immutable). idup returns an immutable copy. So, in this case you want idup, not dup. Even better though, would be to use std.conv.to - e.g. to!string(input). This will convert input to a string, but it has the advantage that if input is already a string, then it'll just return the string rather than making another copy like idup would.
- Jonathan M Davis
|
June 11, 2011 Re: char[] to string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis:
> Even better though, would be to use std.conv.to - e.g. to!string(input). This will convert input to a string, but it has the advantage that if input is already a string, then it'll just return the string rather than making another copy like idup would.
I didn't know this. Isn't it very good to give this bit of intelligence to idup too?
Bye,
bearophile
|
June 11, 2011 Re: char[] to string | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 2011-06-11 05:12, bearophile wrote:
> Jonathan M Davis:
> > Even better though, would be to use std.conv.to - e.g. to!string(input). This will convert input to a string, but it has the advantage that if input is already a string, then it'll just return the string rather than making another copy like idup would.
>
> I didn't know this. Isn't it very good to give this bit of intelligence to idup too?
Except that if you actually need it to create a copy for some reason, then it's a lot harder. However, to!() goes far beyond just improving idup anyway, because to!() should always be avoiding doing conversions if they're not actually necessary. So, if you trying to convert to char[] or const(wchar)[] or whatever, if no conversion is actually necessary, then the original argument will be returned. It doesn't matter what the original argument was. dup and idup only cover the case where you're trying to explicitly copy an array, whereas to!() covers any time that you're trying to convert to one to another type. So, it's generally best to use dup and idup only when you definitely want to make a copy. By using them, you're explicitly stating that you _want_ a copy to be made. If you just want a conversion, then to!() will do the trick in what is hopefully the most efficient way possible.
- Jonathan M Davis
|
June 11, 2011 Re: char[] to string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 2011-06-10 19:56, Jonathan Sternberg wrote:
> Why doesn't this work?
>
> import std.stdio;
>
> string copy_string(char [] input)
> {
> return input.dup;
> }
>
> int main()
> {
> char [] buf = ['h', 'e', 'l', 'l', 'o'];
> writeln( copy_string(buf) );
> }
>
> I want to do something more complex. In my code, I want to have a dynamic array that I can append stuff into and then return it as a string. In C++, a non-const variable can be implicitly converted into a const. I know string is an alias for const char. Is there a reason why it won't implicitly convert it?
>
> I hesitate to use cast for this type of thing as it probably indicates I'm doing something fundamentally wrong as I'm just starting to learn the language.
Hi,
You can append to a string. You only need char[] if you have to modify individual characters.
// idup fixes your specific problem
string copy_string(char [] input)
{
return input.idup;
}
string build_string(string str1, string str2){
string result;
result~=str1;
foreach(i;0..3) result~=str2;
return result;
}
unittest{ assert(build_string("hi","lo") == "hilololo"); }
If you really need char[] and you know that there is only one mutable reference to your data, then you can use std.exception.assumeUnique. (No idea why it is *there* though)
import std.exception;
string toUpper(char[] str){
char[] result = str.dup;
foreach(ref x;result) if('a'<=x && x<='z') x+='A'-'a';
return result.assumeUnique(); // this is only safe if there really is only one
reference to your data
}
Timon
|
June 11, 2011 Re: char[] to string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis:
> it's generally best to use dup and idup only when you definitely want to make a copy. By using them, you're explicitly stating that you _want_ a copy to be made. If you just want a conversion, then to!() will do the trick in what is hopefully the most efficient way possible.
Thank you for the answer. I think this comment needs to go in the online docs (if it's not already present).
Bye,
bearophile
|
Copyright © 1999-2021 by the D Language Foundation