兩種類型不同,當然不能一起操作,會出現編譯錯誤.
從 | 到 |
---|---|
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;
指針轉爲正數
,再轉爲整指針
.