【问题标题】:Why cannot I cast to immutable in @safe functions? (D)为什么我不能在 @safe 函数中强制转换为不可变? (四)
【发布时间】:2013-11-24 13:40:12
【问题描述】:

为什么我不能在@safe 函数中将可变变量转换为不可变值?另外,有没有解决方法?

@safe pure immutable(char[][char[]]) getNameValuePair {
    immutable(char[])[immutable(char[])] pair;
    // logics filling the pair here
    return cast(immutable(char[][char[]])) pair;
}

这段代码会导致编译错误:

错误:安全代码中不允许从 immutable(char[])[immutable(char[])] 转换为 immutable(char[][const(char)[]])

当我执行return pair.idup 时,我收到错误:no property 'idup' for type 'immutable(char[])[immutable(char[])]'

【问题讨论】:

  • 请提供一个你正在尝试做的例子。另请阅读:dlang.org/const3.html。尤其是最后一个例子,作者将可变参数转换为不可变参数。无论如何,这是一个很好的问题,所以+1。 :)
  • @DejanLekic 我在问题中添加了一个示例。

标签: casting d immutability


【解决方案1】:

@safe 的目的是验证内存完整性,强制转换是一个忽略安全并“按我说的做”的命令。我不确定正在做哪些工作来识别“安全”演员表。

一种解决方法是使用@trusted,但最终你只是做错了。您的函数是纯函数,因此它能够分配给不可变实例:

void main()
{
    immutable(char[][immutable(char[])]) ans = getNameValuePair();
}

@safe pure immutable(char[])[immutable(char[])] getNameValuePair() {
    immutable(char[])[immutable(char[])] pair;
    // logics filling the pair here
    return pair;
}

请注意,出现的类型的键是 immutable(char[]) 而不是您尝试转换为的 char[] (从而破坏了您声明的纯/不可变类型的保证)。换句话说,感谢类型系统纠正你的错误。

【讨论】:

    【解决方案2】:

    因为@safe 假设不可变的东西永远不会改变,也就是它试图确保不变量成立

    但是通过强制转换你可以绕过它:

    char[] str = "somestring".dup;
    immutable immutableStr = cast(immutable) str;
    //now immutableStr == "somestring"
    str[0]='S';
    //now immutableStr == "Somestring"
    

    如果您将它用于简单的数组和切片,那么您可以使用 idup 来创建不可变的副本

    【讨论】:

    • 不可变不是应该保证不会更改数据实例吗?
    • 是的,没有关联数组的 idup,抱歉。 cast 关键字也绕过了语言中的许多安全措施,并假设程序员知道他在做什么(意味着许多用途是 @unsafe
    • 那么就没有办法解决了吗?它以这种方式工作有点愚蠢,因为不再有对数组的可变引用。 (函数纯属)
    • @JeroenBollen 曾经有一个 AssumeUnique 允许演员表不可变,但我在库中找不到它
    • @JeroenBolle, @safe 不仅适用于简单数据,而且(更重要的是恕我直言)适用于复杂数据类型,以确保数据的不变性(完整性)。
    猜你喜欢
    • 2016-08-07
    • 1970-01-01
    • 2017-02-19
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    • 2017-11-26
    相关资源
    最近更新 更多