properties - D:常量正确性——我做错了什么?

标签 properties constants d

我目前正在实现一个基于二叉树的数据结构。作为其中的一部分,我有(目前是公开的,以便于测试)实例变量 leftright作为每个 Node 的一部分用于创建我的结构的对象。我希望能够快速访问的一件事是一个 sub,它是使用这个函数完成的:

@property Node sub() 
    in {
        assert(!isLeaf);
    }
    body {
        return (val != left.val) ? left : right;
    }

这里所指的所有东西都是公开的。现在,我尝试在合约中使用这个属性函数(特别是 out block ,函数绑定(bind)到 result 的结果)。但是,当我这样做时,编译器提示我正在使用 const result 调用可变方法。目的。当我更改 sub 的签名时成为 @property const Node sub() ,但是,我得到了这个编译器错误:
Error: cannot implicitly convert expression (this.val != this.left.val ? this.left : this.right) of type const(Node) to tournament2.Node
我在这里想念什么?我该如何解决这个问题?

最佳答案

最初的问题源于合约不能修改它们所属的对象的限制(否则,程序在调试和 Release模式下的行为可能会有所不同)。语言强制执行该限制的方式是使 this指针 const .

一个 const this意思是你不能修改this对象的字段,以及调用方法 - 这些方法本身必须注释为 const ,并且相同的限制适用于这些方法的代码。这解释了第一个错误:契约(Contract),即 const ,试图调用非 const (可变)方法。由于允许修改可变方法this ,并且合约被禁止这样做,编译器禁止调用。

由于 D 的 constness 具有传递性,通过 this 访问的所有内容指针变为 const .并且,如果任何类字段是引用类型,则它们的间接目标变为 const也。这就是类型系统禁止修改任何可以通过 this 访问的内容的方式。指针。

这意味着如果 const方法试图返回一个类字段(具有间接性,例如类类型 Node ),返回的类型也必须是 const .这是第二条错误消息的来源:返回表达式试图转换 const Node值,通过const this获得, 到一个可变的 Node .目前,语法 @property const Node sub()表示方法本身是const (并且具有 const this ),而不是返回类型。

现在,通常,在 C++ 中,具有适当 constness 支持的对象通常会对返回类字段的方法有多个重载:const , 和非 const . const版本将返回 const引用;非const将返回一个非 const引用。当我们可以访问可变对象时,需要这两个版本来获取可变字段引用,但仍然允许获取 const。如果我们只有 const,请引用访问对象。大多数时候,这两种方法的代码是相同的——只是函数签名不同。

这是 D 的 inout在方法和它的一些参数或返回值上指定它意味着这些参数或返回值将具有与 this 相同的常量。 (被引用的对象)。这避免了返回 const 的简单情况下的代码重复。和可变值使用相同的代码。

我使用的语法是@property inout(Node) sub() inout .我认为它可以用不止一种方式编写,但这种语法是明确的。在这里,inout(Node) 中的括号明确说明我们将属性应用于返回值,而不是函数,并放置方法(this)inout参数列表后的属性,如 const在 C++ 中,明确指定它适用于函数本身。

关于properties - D:常量正确性——我做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21694152/

相关文章:

c# - 自定义依赖属性绑定(bind)

java - Java中的时间常数?

c - const 在哪里降低性能而不是优化它?

iteration - 迭代 dlang 结构

d - 无法编译一些简单的 D 代码

c# - 类中的属性/方法占用内存空间吗?

command-line - 子项目的gradle命令行属性

javascript打开新标签,无法从新标签中获取标签和属性,但只能获取null

c++ - std::unique_ptr 转移 const 对象的所有权

memory - 工会占用的内存与其最大类型的成员一样多吗?