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); 

這裏的效果是,原來的可變變量被移動成不變的變量.
而原來的變量被置爲空針了.
上面的toassumeUnique都利用了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;

指針轉爲正數,再轉爲整指針.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章