d有趣的一元重载
import std.stdio;
struct S
{
int value;
alias opCall this;
this(int i) {
value = i;
}
alias opAssign = opCall;
@property opCall(int x) {
return value = x;
}
@property opCall() inout {
return value;
}
@property opOpAssign(string op)(int x) {
write(":"); // 在此前
mixin("return value"~op~"=x;");
}
// 不必: opUnary(string op)();
}
void main()
{
S a = S(10),
b = S(-1);
writeln(a + b); // 9
writeln(++a + b); // :10
a += 10; // :
assert(a == 21);
writeln("\n--");
writeln(-b); // 1
}
是的,有趣,我加了些注解
:
import std.stdio;
struct S
{
int value;
说明允许此类型
对象隐式
转换为'int'
('opCall'
返回类型).
即,由于opCall
返回'int'
,现在知道S对象
可隐式代替int
.调用opCall
来确定值
.
opCall
允许像函数一样对待对象
.如,当有"obj"
时,可'obj()'
.
注意:这让我有点困惑
,因为下面有两个opCall
定义,它们都返回"int"
.但是,因为下面这句
,编译器选择无参
的别名本
,所以没有歧义
.
alias opCall this;
this(int i) {
value = i;
}
你正在为opCall
指定(opAssign)
新名.编译器是否考虑opCall
来赋值,或它在找正确的opAssign
定义:
alias opAssign = opCall;
这是带'int'
函数调用符,支持obj(42)
等用法.
@property opCall(int x) {
return value = x;
}
这是空参调用opCall
,支持obj()
用法.
@property opCall() inout {
return value;
}
这是'obj+=42'
等用法的操作符重载
.
@property opOpAssign(string op)(int x) {
write(":");
mixin("return value"~op~"=x;");
}
// 不需要: opUnary(string op)();
}
void main()
{
/*这是普通构造对象*/
S a = S(10),//有个逗号
b = S(-1);
由于S未定义"+"
操作,编译器会查找
隐式转换,恰好是"int"
.以下表达式是两个整数
的加法:10+(-1)
writeln(a + b); // 9
尽管S不支持++
运算符,但D编译器会找到+=
操作并用a+=1
替换++
.然后隐式转换a
为'int'
,得到11
.同样,表达式是11+(-1)
的整数加法
.
writeln(++a + b); // :10
/* 用opOpAssign. */
a += 10; // :
/* 结果有意义. */
assert(a == 21);
writeln("\n--");
writeln(-b); // 1
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现