我即将编写一个解析器,按行读取文本文件并将其转换为不同类型的结构体,并将这些结构体传递给回调函数(观察者或访问者 - 尚不确定)。
文本文件包含MT-940数据 - SWIFT银行对账单。
这些行由指定类型和一些字段(例如日期)的标记组成,应将这些字段解析为我的消息的类型安全成员。其中一些字段是可选的 - 所以我的问题是:如何在D中表示可选值。
C ++提供了很多像boost :: optional这样的东西,你可能知道。
我目前通过自己实现Optional(T)来解决此问题(请参见本帖子末尾的代码)。它是一个包含ValueHolder实例的结构体,该实例可能为null - 表示未分配任何值的情况。我重写了复制构造函数和赋值运算符以创建ValueHolder的深度副本(如果必要)。
这是我的代码 - 可能还不完整:
struct Optional(T)
{
class ValueHolder
{
T value;
this(T v)
{
value = v;
}
}
private ValueHolder m_value;
/* Construction without value / with value */
this(T value)
{
m_value = new ValueHolder(value);
}
/* Copy construction / assignment */
ref Optional!(T) opAssign(Optional!(T) rhs)
out
{
if (rhs.m_value !is null)
{
assert(rhs.m_value != m_value);
}
else
{
assert(m_value is null);
}
}
body
{
m_value = null;
if (rhs)
{
m_value = new ValueHolder(rhs.m_value.value);
}
return this;
}
ref Optional!(T) opAssign(T value)
out
{
assert(hasValue());
assert(m_value.value == value);
}
body
{
if (m_value is null)
{
m_value = new ValueHolder(value);
}
else
{
m_value.value = value;
}
return this;
}
this(Optional!(T) rhs)
out
{
if (rhs.m_value !is null)
{
assert(rhs.m_value != m_value);
}
else
{
assert(m_value is null);
}
}
body
{
if (rhs.m_value !is null)
{
m_value = new ValueHolder(rhs.m_value.value);
}
}
/* Implicit cast to bool */
bool hasValue() const
{
return m_value !is null;
}
X opCast(X: bool)()
{
return hasValue();
}
/* Value access */
T opUnary(string s)() const
in
{
assert(s == "*");
assert(m_value !is null);
}
body
{
return m_value.value;
}
}
/* Default Constructed Struct does not have a value assigned */
unittest
{
Optional!(int) x;
assert(x.hasValue() == false);
assert(!x);
}
/* Construction with value */
unittest
{
Optional!(int) x = 3;
assert(x);
assert(x.hasValue());
}
/* Assignment operator does copy the value */
unittest
{
Optional!(int) x = 3;
Optional!(int) y;
assert(x);
assert(!y);
y = x;
assert(&x != &y);
assert(x);
assert(y);
y = 12;
assert(x.m_value.value != y.m_value.value);
assert(*y == 12);
Optional!(int) z;
x = z;
assert(!x);
assert(!z);
assert(y);
}
Nullable!T
用作T
时,它确实会检查其是否为 "null"。 - Jonathan M Davis