为什么我不能将可变变量转换为@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[])]'
。
答案 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创建一个不可变的重复