调用 class 析构函数时 InvalidMemoryOperationError@
InvalidMemoryOperationError@ on call of class destructor
计划是在调用 class 析构函数时使用模板记录消息,但这似乎不可能。任何建议或解释将不胜感激。
import std.stdio;
import std.datetime;
class Test
{
this()
{
struct Start
{
string filename;
}
Message!(Start)(Start("one.txt\n"));
}
~this()
{
struct Stop
{
string filename;
}
Message!(Stop)(Stop("stop one.txt\n")); // > core.exception.InvalidMemoryOperationError@(0)
// auto t = Clock.currTime().toISOString(); // > core.exception.InvalidMemoryOperationError@(0
}
}
unittest
{
auto t = new Test();
}
struct Message(T)
{
this(T message)
{
_time = Clock.currTime().toISOString();
writefln("%s: %s", _time, message.filename);
}
string _time;
}
不允许在 GC 运行ning 期间分配 GC 内存。由于 class 析构函数通常由 GC 运行,结果是你不应该在那里使用它。
还值得注意的是,在 class 析构函数中不允许通过引用访问其他 GC 成员,因为对象的成员可能与对象本身同时被释放,因此在该上下文中不可用.
所以诀窍是摆脱 toISOString 调用和对 struct.toString.
的隐式调用
这会更好:
struct Message(T)
{
this(T message)
{
auto time = Clock.currTime();
writefln("%d:%02d:%02d %s(%s)",
time.hour, time.minute, time.second,
T.stringof, message.filename);
}
}
通过在组件之外的 writefln 中自己构建字符串而不是依赖 returns 新字符串的函数,我们停止分配,防止异常。
计划是在调用 class 析构函数时使用模板记录消息,但这似乎不可能。任何建议或解释将不胜感激。
import std.stdio;
import std.datetime;
class Test
{
this()
{
struct Start
{
string filename;
}
Message!(Start)(Start("one.txt\n"));
}
~this()
{
struct Stop
{
string filename;
}
Message!(Stop)(Stop("stop one.txt\n")); // > core.exception.InvalidMemoryOperationError@(0)
// auto t = Clock.currTime().toISOString(); // > core.exception.InvalidMemoryOperationError@(0
}
}
unittest
{
auto t = new Test();
}
struct Message(T)
{
this(T message)
{
_time = Clock.currTime().toISOString();
writefln("%s: %s", _time, message.filename);
}
string _time;
}
不允许在 GC 运行ning 期间分配 GC 内存。由于 class 析构函数通常由 GC 运行,结果是你不应该在那里使用它。
还值得注意的是,在 class 析构函数中不允许通过引用访问其他 GC 成员,因为对象的成员可能与对象本身同时被释放,因此在该上下文中不可用.
所以诀窍是摆脱 toISOString 调用和对 struct.toString.
的隐式调用这会更好:
struct Message(T)
{
this(T message)
{
auto time = Clock.currTime();
writefln("%d:%02d:%02d %s(%s)",
time.hour, time.minute, time.second,
T.stringof, message.filename);
}
}
通过在组件之外的 writefln 中自己构建字符串而不是依赖 returns 新字符串的函数,我们停止分配,防止异常。