19用d编程转换
两种类型不同,当然不能一起操作,会出现编译错误.
从 | 到 |
---|---|
bool | int |
byte | int |
ubyte | int |
short | int |
ushort | int |
char | int |
wchar | int |
dchar | uint |
类型提升,从低到高.没问题,不会出现截断
.
int a = 0;
int b = 1;
size_t c = 0;
writeln(a - b + c); //最大整
因为没有-1的正整数.
切片也可指向静态数组
import std.stdio;
void foo() {
int[2] array = [ 1, 2 ];
bar(array);//静态数组
}
void bar(int[] slice) {//切片
writeln(slice);
}
void main() {
foo();
}
不要返回局部切片,不然你返回的是个悬挂指针.
import std.stdio;
void foo() {
int[2] array = [ 1, 2 ];
bar(array);//静态数组
} //在此外数组就释放了
int[] sliceForLaterUse;//全局
void bar(int[] slice) {//进来的切片参数可疑
sliceForLaterUse = slice;//这里复制的是钥匙
//全局变量钥匙指向局部钥匙.
writefln("钥匙内部: %s", sliceForLaterUse);
}
void main() {
foo();
writefln("全局钥匙: %s", sliceForLaterUse);
}
总感觉d
把事情搞复杂了.不如c++
.谁知道切片是个钥匙还是个实体啊,难道还要去猜,去动脑壳想?
按生命期理论
.就是大生命期
的钥匙/指针不能指向小生命期
的钥匙/指针
.否则就是崩溃之源.
char[] parenthesized(const char[] text) {
return "{" ~ text ~ "}";
}
void main() {
char[] greeting;
greeting ~= "你好世界";
parenthesized(greeting);
}
常转,非常->常
.没问题.这是加限制
.
char[] parenthesized(const char[] text) {
char[] argument = text;//编译错误
...
}
常=>非常
,对不起,编译错误.上面的针对的是引用.
const int totalCorners = 4;
int theCopy = totalCorners;
这是复制值,所以没问题.
string a = "你好"; // 不变
char[] b = a;//编译错误
string c = b;//编译错误
//仍然是针对引用类型.
immutable a = 10;
int b = a;// 编译,值类型
枚举类型
.枚可直接
转成整数
,参与运算.
int result = 10 + Suit.hearts;
assert(result == 11);
Suit suit = 2; //编译错误
极值
转换
int a = false;
assert(a == 0);
int b = true;
assert(b == 1);
bool a = 0;
assert(!a); // 假
bool b = 1;//0,1可转换,其余不行
assert(b); // 真
int i;
// ...
if (i) { //
// 非零
} else {
// ... i==0
}
int[] a;
// ...
if (a) {
//非空针
} else {
//空针
}
以下情况不会自动
转换:
1,宽->窄
.
2,常->变
3,不变
转换至其他
4,整至枚
.因为枚
更限定.
如果是安全的,得显式
转换:
1,构造符
.
2,std.conv.to
,
3,std.exception.assumeUnique
,
4,cast(...)
,
如:
int i;
//DestinationType(value)
// ...
const result = double(i) / 2;
//类型(..)
to!(DestinationType)(value)
//直接搞,犯错.
void main() {
double d = -1.75;
short s = d; // 编译错误
int i = "42"; // 编译错误
}
//这样就行了.
import std.conv;
void main() {
double d = -1.75;
short s = to!short(d);
assert(s == -1);
int i = to!int("42");
assert(i == 42);
}
//也可转不变
int[] slice = [ 10, 20, 30 ];
auto immutableSlice = to!(immutable int[])(slice);//其实与`.idup`没啥区别.
//
assert(&(slice[0]) != &(immutableSlice[0]));
//新实体了.
移动
变为不变
void calculate(immutable int[] coordinates) {
// ...
}
void main() {
int[] numbers;
numbers ~= 10;
// ... 其他修改...
numbers[0] = 42;
calculate(numbers); // 编译错误
}
//编译错误
import std.exception;
// ...
auto immutableNumbers = assumeUnique(numbers);
calculate(immutableNumbers);
assert(numbers is null);
这里的效果是,原来的可变
变量被移动成不变
的变量.
而原来的变量被置为空针
了.
上面的to
与assumeUnique
都利用了cast
cast(DestinationType)value
.
to不行的地方.
Suit suit = to!Suit(7); //抛异常
bool b = to!bool(2); //
虽然可能不正确,这时由程序员
保证正确性
.
//可能不正确,但能够通过编译
Suit suit = cast(Suit)7;
bool b = cast(bool)2;
assert(b);
指针间类型转换,只能通过cast
:
void * v;
// ...
int * p = cast(int*)v;
cast
是不安全的,危险的.还可以:
size_t savedPointerValue = cast(size_t)p;
// ...
int * p2 = cast(int*)savedPointerValue;
指针转为正数
,再转为整指针
.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现