【发布时间】:2012-08-11 10:56:23
【问题描述】:
代码
string bar = "Hello ";
const(char) * foo = "world!";
bar ~= foo;
在第三行编译失败。为什么?我有什么优雅的替代品?
错误输出为Error: cannot append type const(char)* to type string。
【问题讨论】:
标签: string concatenation d
代码
string bar = "Hello ";
const(char) * foo = "world!";
bar ~= foo;
在第三行编译失败。为什么?我有什么优雅的替代品?
错误输出为Error: cannot append type const(char)* to type string。
【问题讨论】:
标签: string concatenation d
不要使用const(char)*?
string bar = "Hello ";
string foo = "world!";
bar ~= foo;
D 中的字符串字面量属于 string 类型,您永远不需要使用 const(char)*,除非与 C 代码交互。
D 不允许这种连接的原因是因为const(char)* 在任何意义上都不是字符串。 D 中的字符串是immutable(char)[](即alias'd by string)。 const(char)* 只是一个指向常量字符的指针。与 C 和 C++ 不同,没有隐含的空终止符,因此 D 不能也不会假设存在空终止符。
如果出于某种原因您绝对必须使用 const(char)* 并且您知道它是空终止的,那么您可以通过切片将 const(char)[] 从中取出,然后您可以附加给string:
string bar = "Hello ";
const(char)* foo = "world!";
bar ~= foo[0..strlen(foo)];
【讨论】:
foo 不会给你string,而是const(char)[]。它仍然兼容与string bar 的连接,但如果您尝试将切片foo 的结果存储在string 变量中,则会出现错误。
string 不能保证为空终止符,您不应在末尾添加空终止符,否则会增加 string.length。传递给 C 函数时,使用toStringz(myString)。
string 是immutable(char)[] 的别名,即不可变字符的可变切片。 bar 在您的代码中是这种类型的数组切片。
const(char)* 和 D 中的字符串字面量之间的关系只是字符串字面量总是以 null 结尾,并且键入为immutable(char)[](即string)或immutable(char)*,以便与 C 代码进行互操作;后者可以隐式转换为const(char)*。需要注意的是,这仅适用于 字符串字面量:在一般情况下,数组不一定以 null 结尾,并且它们不可隐式转换为等效的指针 (尽管任何切片 T[] 的成员 .ptr 的类型为 T* 并指向切片的第一个元素。
连接运算符与数组以及具有相关运算符重载的用户定义类型一起使用,仅此而已。由于 D 不允许为内置类型重载运算符,因此无法使它们与指针一起使用。
解决方案是通过使用适用于数组和指针的切片运算符,对指针指向的字符串进行切片:
import core.stdc.string : strlen;
string bar = "Hello ";
const(char)* foo = "world!";
bar ~= foo[0 .. strlen(foo)];
在上面,表达式foo[0 .. strlen(foo)] 是const(char)[] 类型,可以与bar 连接,immutable(char)[] 类型是immutable(char)[](即string)。
【讨论】: