d中不变与数组
原文
rumbu
:想理解编译器行为:
struct SimpleStruct { int x;}
struct ComplexStruct { int[] x; }
void main()
{
SimpleStruct[] buf1;
immutable(SimpleStruct)[] ibuf1;
buf1[0 .. 10] = ibuf1[0 .. 10];
//工作
ComplexStruct[] buf2;
immutable(ComplexStruct)[] ibuf2;
buf2[0 .. 10] = ibuf2[0 .. 10];
//错误,不能隐式转换`immutable(ComplexStruct)[]`类型的`ibuf2[0..10]`到`ComplexStruct[]`
}
WebFreak001
:
规范说:
无可变间接引用
值(包括不含
具可变间接引用
字段的构)可在mutable,const,immutable,const shared,inout
和inout shared
间隐式转换.
因此第一个
结构可在可变/不变/常
间隐式转换,因为它不包含(可变数组/指针/引用)
的可变间接.
Stanislav Blinov
:因为is(typeof(immutable(ComplexStruct).x)==immutable(int[]))
.不能绑定不变
数组到可变
数组.需要深复制
,即复制构造器
.
Steven Schveighoffer
:
第一例,有个包含整数的简单结构
.复制该构
时,无间接(指针)
,即允许调整可变性
:
immutable s = SimpleStruct(5);
SimpleStruct s2 = s; // 好,复制所有
第二例,int[]
包含指针
.如果复制它,就不能改变类型
的可变性
,因为它有到不变数据
的可变指针
:
immutable s = ComplexStruct([5]);
ComplexStruct s2 = s; // 错误,不能隐式转换,有个`间接`.
为什么?假设允许它,s2
是可变的,即s2.x
是可变的.现在可这样:
s2.x[0] = 6;
突然之间,可修改不变数据
了!这是禁止
的,因而不能复制结构
.
Stanislav Blinov
:
不完全是.这里可能有个真正
错误:
struct S
{
int[] x;
// 没用它,后复制也不行
this(ref return scope inout S other)
{
x = other.x.dup;
}
void opAssign(ref return scope inout S other)
{
x = other.x.dup;
}
}
void main()
{
immutable(S)[] src = [S([1, 2]), S([3, 4])];
auto dst = new S[src.length];
//dst[0 .. $] = src[0 .. $];
//即使定义了`opAssign`,也不编译
//这可以:
foreach (i, ref it; dst)
it = src[i];
}
规范:
根据规范,(在检查重叠
后),分配切片
应与foreach
循环一样.但没有,只是尝试隐式转换
,但失败了.
现在,因为有了复制构造器
,切片赋值
应该尝试复制赋值
元素(即无opAssign
时,先试复制构造器
).
Steven Schveighoffer
:
我同意在此切片赋值
同复制构造器
应工作.我认为目前是它仍依赖memcpy+后复制
,(数组运行时
多数还是神奇
函数).
后复制
不管用,因为它先按原样
复制数据,即仍然是不变
的,只有在后复制
之后才是可变的.
注意
,这不是构造
,它应该用opAssign
.再说一遍,可能是运行时用了memcpy+后复制
.如果无报告,应该是这样.
简单证明这是漏洞:
immutable (ComplexStruct)[] arr;
ComplexStruct[] arr2;
arr2[0] = arr[0]; // ok
arr2[] = arr[]; // 错误
如果可复制元素
,则应可复制所有元素
.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现