联.
联
的成员共享内存占用.也可有成员函数
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.variant
的Algebraic 和 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当然也有.