无法将常量(结构)类型附加到数组

发布于 2024-10-17 14:28:15 字数 416 浏览 4 评论 0原文

在一个结构体中,Shape I 有一个函数:

...
import graphics.line;

struct Shape {
    Line[] lines;

    void addLine(Line l) {
        lines ~= l;
    }
}

Line 也是一个结构体,但是当我将“in Line l”作为 addLine() 的参数声明时, 编译器出现错误:

shape.d(12):错误:无法附加类型 const(Line) 来输入 Line[]

奇怪的是我在另一个模块中有一段类似的代码,并且它有效......所以我的问题是,为什么编译器在这种情况下对此不满意?

In one struct, Shape I have a function:

...
import graphics.line;

struct Shape {
    Line[] lines;

    void addLine(Line l) {
        lines ~= l;
    }
}

Line is also a struct, but when I put "in Line l" as the argument declaration for addLine(),
the compiler bugs out with:

shape.d(12): Error: cannot append type
const(Line) to type Line[]

The weird thing is I have a similar piece of code in another module, and it works... So my question is, why is the compiler not happy with it in this case?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

罪#恶を代价 2024-10-24 14:28:15

基本上,这是否有效取决于您的结构具有哪些成员。
存储类相当于const作用域。所以,写
void addLine(in Line l) 表示 l 是 const。由于 const
传递性,所有 Line l 结构成员也是 const

然而,Shape 成员 Line[]lines 不是 const。所以,你正在尝试
const Line l 附加到非 const 的内容。这是否是
可能取决于 struct Line l 的所有成员的类型。如果全部
line 的成员具有值(复制)语义,此附加(这是一个
分配)是可能的。如果任何一个成员具有(某些)参考语义(例如
指针被复制),这种附加不再可能。否则,你
可以将 const Line lc 放入 addLines 中,但会得到一个非常量成员
。通过这个,您可以使用引用语义更改值,
也间接改变了原始lc的值,从而违反了
const 保证,即 D 中 const 的传递性。

示例:

class C { }

struct Line {
    int i;
    // int* p;               // if you uncomment this, addLine fails
    // C c;                  // if you uncomment this, addLine fails
}

struct Shape { 
    Line[] lines;
    void addLine(in Line l) { lines ~= l; }
}

void main() { }

编辑: BTW,另一种使其工作的方法是更改​​ Line[]lines;const(Line)[]lines;。该数组仅包含 const 元素,并且可以在 addLine 中附加 const l

Basically, whether this works depends on what members your struct has. The in
storage class is equivalent to const scope. So, writing
void addLine(in Line l) means that l is const. And since const is
transitive, all Line l struct members are const, too.

The Shape member Line[] lines is however not const. So, you are trying to
append a const Line l to something that is not const. Whether this is
possible depends on the types of all members of the struct Line l. If all
members of line have value (copy) semantics, this appending (which is an
assignment) is possible. If any one member has (some) reference semantics (e.g.
a pointer gets copied), this appending is no longer possible. Otherwise, you
could give a const Line lc into addLines, but would get a non-const member
of lines. Through this, you could change the value with reference semantics,
changing the value of the original lc indirectly, too, thereby violating the
const guarantee, namely the transitivity of const in D.

Example:

class C { }

struct Line {
    int i;
    // int* p;               // if you uncomment this, addLine fails
    // C c;                  // if you uncomment this, addLine fails
}

struct Shape { 
    Line[] lines;
    void addLine(in Line l) { lines ~= l; }
}

void main() { }

Edit: BTW, another way to make it work is to change Line[] lines; to const(Line)[] lines;. Than the array contains only const elements, and the appending of a const l in addLine is possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文