为什么我不能在@safe函数中转换为不可变的? (d)

时间:2013-11-24 13:40:13

标签: casting d immutability

为什么我不能将可变变量转换为@safe函数中的不可变值?此外,有一个解决方法吗?

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

此代码将导致编译错误:

  

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

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

2 个答案:

答案 0 :(得分:3)

@safe的目的是验证内存的完整性,cast是一个忽略安全的命令,“按我说的去做”。我不确定正在做什么工作来识别“安全”演员。

解决方法是使用@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;
}

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

答案 1 :(得分:2)

因为@safe假设某些不可变的东西不能改变,也就是它试图确保不变量保持

然而,通过施法,你可以绕过它:

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

如果您将它用于简单数组和切片,那么您可以使用idup创建一个不可变的重复