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;
指针转为正数,再转为整指针.
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号