d的和类型
理由
和类型(sumtype)
在许多语言中都是有用和流行
的.和
类型与证明是有用和流行
的模式匹配
配合得很好.与C风格
的无标签联
相反,和类型
主要特征是保证
安全访问成员.并保证处理和类型
的所有情况.Sumtypes
是可靠避免常见编程的在不先检查值
是否无效
下就访问
值的错误.当函数需要指示有错误及返回错误无效
时,Sumtypes
是抛
异常的替代
方法.
先前工作
std.和类型
同D受限的表现力工作时,它是出色
的实现,但因为要用类型
来指定和类型
的用例,有限制
.这里
1,std.和类型
不能包含普通
枚举成员
2,std.和类型
无法优化不存在的标签,如,当有:
enum Option { None, int* Ptr }
3,如果模式匹配
中未考虑所有情况,则不会产生编译时
错误,而是抛异常
4,无法提取子匹配
并赋值
给其他变量
5,仅按类型而不是按值匹配
6,整(int)
和指针
不能同时且安全
的在和类型
中.
7,不能有属于同一
类型的两个
字段声明
swift
rust
c++
描述
和
类型有一组独特
命名成员.任一时候,只能有
一个这些成员.由叫标签
的隐藏字段
指定是哪一个
.
和
类型具有枚举,构和联
的特征.因为可包含一组命名
整数值,像枚举
.因为它包含一个标签
和一个和
类型的所有成员
的联
的两个字段
,又像一个构
.又因为所有成员共享第二个
字段,又像一个联
.
和
类型大小是:标签
大小+
最大成员+
对齐填充
.
字段声明
的成员函数
受联的成员函数
的限制
.
和
类型的成员可有由实现按顺序
赋值的整数值
,程序员赋值
的唯一整数值
,也可是指定类型值
.
和类型
的第一个成员
默认是它的初值
.可复制和类型
.
和类型
的成员不能有复制构造器
,后复制(postblit)
或析构器
.
和类型
的枚举成员
类型是可表示所有枚举成员值
的最小类型
.如果没有负值
,则用正
类型.
和类型
特例允许使用非空针
.
引入了新QueryExpression
式,可查询和类型
是否包含指定成员
.
语法
SumTypeDeclaration:
`和类型` Identifier SumTypeBody
SumTypeTemplateDeclaration
SumTypeBody:
`{` SumTypeMembers `}`
SumTypeMembers:
SumTypeMembers
SumTypeMember `,`
SumTypeMember `,` SumTypeMembers
SumTypeMember:
EnumMemberAttributes SumTypeMember
EnumMember
FieldDeclaration
EnumMember:
Identifier
Identifier = AssignExpression
FieldDeclaration:
Type Identifier
Type Identifier = AssignExpression
SumTypeTemplateDeclaration:
`和类型` Identifier TemplateParameters Constraint (opt) SumTypeBody
QueryExpression:
`?` PostfixExpression `.` Identifier
替代语法
和类型 Option(T) = None | Some(T);
对比:
和类型 Option(T) { None, Some(T) }
示例
函数
可返回两种类型,一种
表示错误
,另一个是结果
.可实现为:
和类型 Result
{
Error,
int Value
}
Result func()
{
Result res; // 初化为Result.Error
if (things went well)
res.Value = 25; // 非错误结果
return res;
}
void plugh()
{
Result ret = func();
if (?ret.Error)
printf("中错误\n");
else
printf("结果是%d\n", ret.Value);
}
如果在Kod
中存储整
,则只能(通过运行时
检查标签)提取整
.对整*
来说也一样.因此,虽然整
和整*
占用相同存储
空间,但不能混为一谈.Kod
的大小会占用2个整
,一个是标签
,一个是x|y
.
enum Kod
{
int x;
int* p;
}
模板
可像构
声明一样参数化和类型
:
enum Option(T)
{
int Integer,
T Other,
}
查询式
如果和类型
包含指定变量
,查询式返回真
,否则假
.
x = Xyzzy.busy;
if (?x.busy)
writeln("busy");
else
writeln("not busy");
安全
想法是避免
访问(由标签
指定的)不在和类型
中值.
写
写入
和类型是安全
的,因为它会用新值重写
现有值.
enum Xyzzy { busy, int allow, int* ptr }
Xyzzy x;
x = Xyzzy.busy; // 好
x = Xyzzy.allow(3); // 好
int i;
x = Xyzzy.ptr(&i); // 好
读
只能读取
实际在和类型
中的值:
Xyzzy x = Xyzzy.busy;
Xyzzy y = x.busy; // 好
y = x.allow; // 运行时错误
y = ?x.allow ? x.allow : Xyzzy.busy;
x = Xyzzy.allow(3);
y = x.allow; // 好
指针和引用
对调用和类型
成员函数,和类型
的类型成员
的指针和引用
是很有用的.会造成
以下问题:
int i;
Xyzzy x = Xyzzy.allow(3);
int** p = &x.allow; // 好
x = Xyzzy.busy;
*p = null; // 出错
目前最务实
方法是,在@safe
中,简单禁止
使用和类型
成员的地址或引用
.
隐式转换和转换
和类型
不会与其他类型
隐式互转换
.
是式(IsExpressions)
使用sumtype
关键字扩展是式
来标识和类型
.
混杂名
添加TypeSubtype
.
TypeSubtype:
`No` QualifiedName
非空针特例
可用sumtypes
来创建非null
指针.如,以下在Null
成员和Ptr
成员之间共享存储
.因此,不检查Null
就无法提取Ptr
,默认初化指针(Pointer)
为Null
.
和类型 Pointer
{
Null,
int* Ptr,
}
Pointer nnp; // 默认初化为Pointer.Null
if (?nnp.Null) printf("null pointer\n"); // 好
int* p = nnp.Ptr; // 运行时错误
int i;
nnp.Ptr = &i;
p = nnp.Ptr; // 好
这里问题是:
nnp.Ptr = cast(int*)null;
p = nnp.Ptr; // 编译, 但置p=null
解决方法
是识别
,是0成员+指针
形式.然后,和类型
用指针合并标签
.因此如果赋值空针
给和类型
,则和类型
用Null
打标签.禁止空针
的语言不需要该特例
.
在DMD
中的实现
和类型共享enums,structs,和union
的特征.按其中之一的和类型
实现可能太复杂,不值得
.因此,为它构建新类型和新声明
.
但由于可按枚举
实现只有枚举
成员的和类型
,编译器
应重写它.同样,只一个字段
的和类型
声明应按构重写
(并省略标签).此外,可按指针
重写值为0
的枚举
成员及1个指针
的字段声明的和类型
.
匹配模式
适合访问
和类型的模式匹配
语句是另一个DIP
的主题.
未来方向
除了枚举
成员和字段
声明外,还可添加元组
声明.
中断和弃用
已在火卫一中按模块名
用和类型
.必须:
0,查找其他关键字
1,更改std.sumtype
模块名
2,使用环境
相关关键字
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现