43用d编程-联

联.
的成员共享内存占用.也可有成员函数

struct S {
    int i;
    double d;
}

// ...

    writeln(S.sizeof);
//用-m32编译,上为12,下为8
union U {
    int i;
    double d;
}

// ...

    writeln(U.sizeof);

目的是为了不同时间对相同区域按不同类型处理.可能不能跨平台,但可用来访问其他成员的碎片.
下例用typeid仅允许访问当前有效成员.

    auto u = U(42);
    writeln(u.d);  

用整初化,访问双精成员.依赖于不同微控器(平台)的大小头,值可能不一样.
匿名联:

struct S {
    int first;

    union {
        int second;
        int third;
    }
}

// ...

    writeln(S.sizeof);//8

ip地址:

union IpAddress {
    uint value;
    ubyte[4] bytes;
}
import std.stdio;

void main() {
    auto address = IpAddress(0xc0a80102);
    writeln(address.bytes);
}

在小头系统为[2, 1, 168, 192],除了被初化的值,不保证其余值.

import std.system;//endian,大小头.
import core.bitop;//bawap处理字节序,交换字节后返回参数

// ...

    if (endian == Endian.littleEndian) {
        address.value = bswap(address.value);
    }//`[192, 168, 1, 2]`

示例,通讯协议
协议包中特殊字段规定当前包是什么样的信息.

struct Host {
    // ...
}

struct ProtocolA {
    // ...
}

struct ProtocolB {
    // ...
}

enum ProtocolType { A, B }

struct NetworkPacket {
    Host source;
    Host destination;
    ProtocolType type;//利用这个判断是A还是B协议

    union {
        ProtocolA aParts;
        ProtocolB bParts;
    }

    ubyte[] payload;
}

区分联是带类型安全的联,它不允许访问当前有效成员外的成员.

import std.stdio;
import std.exception;

struct Discriminated {
private:

    TypeInfo validType_;
    union {
        int i_;
        double d_;
    }

public:

    this(int value) {// 调用下面属性:
        i = value;
    }

    @property void i(int value) {//置器
        i_ = value;
        validType_ = typeid(int);
    }

    @property int i() const {//取器
        enforce(validType_ == typeid(int),"非'int'.");
        return i_;
    }

    this(double value) {
        d = value;
    }

    @property void d(double value) {//置器
        d_ = value;
        validType_ = typeid(double);
    }

    @property double d() const {//双精的取器
        enforce(validType_ == typeid(double),"非'double'." );
        return d_;
    }

    @property const(TypeInfo) type() const {
        return validType_;
    }//类型
}

unittest {
    auto var = Discriminated(42);
    assert(var.type == typeid(int));
    assert(var.i == 42);
    assertThrown(var.d);//失败
    var.d = 1.5;
    assert(var.type == typeid(double));
    assert(var.d == 1.5);
    assertThrown(var.i);
}

即同一时刻只一个管用的类型.
上面是例子,你可以考虑在你程序中使用std.variantAlgebraic 和 Variant.
上面代码可利用mixin减少重复.

void main() {
    Discriminated[] arr = [ Discriminated(1),
                            Discriminated(2.5) ];
    foreach (value; arr) {
        if (value.type == typeid(int)) {
            writeln("同'int'  : ", value.i);

        } else if (value.type == typeid(double))  {
            writeln("同'double': ", value.d);

        } else {
            assert(0);
        }
    }
}

可如上使用.这,其实就是个c++的变量,d当然也有.

发布了440 篇原创文章 · 获赞 29 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/fqbqrr/article/details/104589709