繁体   English   中英

D:Const正确性 - 我做错了什么?

[英]D: Const correctness - what am I doing wrong?

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

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

这指的所有内容都是公开的。 现在,我尝试在契约中使用此属性函数(特别是out块,其结果是函数绑定到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

我在这里错过了什么? 我该如何解决这个问题?

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

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

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

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

现在,通常,在C ++中,具有适当const支持的对象通常会为返回类字段的方法提供多个重载: const和non const const版本将返回一个const引用; const将返回非const引用。 当我们访问可变对象时,需要两个版本来允许获取可变字段引用,但如果我们只有对该对象的const访问权限,则仍允许获取const引用。 大多数情况下,两种方法的代码是相同的 - 只有函数签名才会有所不同。

这是D的inout用武之地。在方法以及它的一些参数或返回值指定这意味着这些参数或返回值将具有相同的常量性作为的this (对象被称为)。 这避免了返回const和mutable值使用相同代码的简单情况下的代码重复。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM