天天看點

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