【问题标题】:Can't define an associative array type: opEquals doesn't exist无法定义关联数组类型:opEquals 不存在
【发布时间】:2015-01-16 00:02:51
【问题描述】:

我不能使用非原始类型作为关联数组的键;尝试这样做会导致我定义 AA 的行出现以下错误:

Error: AA key type MyString does not have 'bool opEquals(ref const MyString) const

我在使用 CollisionHandler[Tuple!(TypeInfo, TypeInfo)] 类型时首次发现了这一点,其中 CollisionHandler 是函数指针类型的别名。

但是,即使 Associative array documentation page 下的“使用结构或联合作为 KeyType”标题中的示例代码也会失败并出现相同的错误:

import std.string;

struct MyString
{
    string str;

    size_t toHash() const @safe pure nothrow
    {
        size_t hash;
        foreach (char c; str)
        hash = (hash * 9) + c;
        return hash;
    }
    // opEquals defined here?
    bool opEquals(ref const MyString s) const @safe pure nothrow
    {
        return std.string.cmp(this.str, s.str) == 0;
    }
}

int[MyString] foo; // errors here

void main() {

}

这里,MyString.opEquals 被定义并且应该有正确的签名,但是 dmd 编译器说它没有被实现。这个 sn-p 直接来自文档的事实让我怀疑这是一个编译器错误,但也许我只是遗漏了一些东西?

在 Linux 下运行 DMD,但在 Windows 7 下也会出现此问题。DMD 版本:

$ dmd --help
DMD64 D Compiler v2.066.1
Copyright (c) 1999-2014 by Digital Mars written by Walter Bright
Documentation: http://dlang.org/
...

【问题讨论】:

    标签: d


    【解决方案1】:

    这是编译器发出误导性错误消息的情况。

    问题在于opEquals 方法上的@safe 注释。在 2.066.1 中,std.string.cmp 不是 @safe - 但是,编译器会显示错误的错误消息。如果您将 opEquals 重命名为其他名称,例如foo,你会得到不同的错误信息:

    test.d(19): Error: safe function 'test.MyString.foo' cannot call system function
    'std.algorithm.cmp!("a < b", string, string).cmp'
    

    解决方法是删除@safe,或将其替换为@trusted

    注意这个问题在DMD的开发版本中没有表现出来,所以应该在2.067.0中修复。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-24
      • 2018-02-26
      • 2021-08-09
      • 1970-01-01
      相关资源
      最近更新 更多