"this T" 的奇怪行为
Weird behavior with "this T"
有人可以向我解释以下行为吗?
有了这样的基础 class:
abstract class Foo
{
string[] members;
final:
this(this T)(T child)
{
import std.conv : to;
foreach (member; __traits(derivedMembers, T))
{
mixin("members ~= to!string(child." ~ member ~ ");\r\n");
}
}
void printMembers()
{
writeln(members);
}
}
我希望使用传递的子类型的值填充成员。
但是行为真的很奇怪。
数组成员将被无限填充,这基本上会导致程序内存不足。
如果将 mixin 更改为:
mixin("if (members.length < 20) members ~= to!string(child." ~ member ~ ");\r\n");
然后您将能够看到数组是如何填充的,但是这些值对于代码的工作方式没有意义。
用法示例:
class Bar : Foo
{
int baba;
int caca;
this() { baba = 1; caca = 2; super(this); }
}
class Baz : Foo
{
int foo;
int bar;
int baz;
this() { foo = 100; bar = 200; baz = 300; super(this); }
}
void main()
{
auto b = new Bar();
auto a = new Baz();
b.printMembers();
a.printMembers();
b.printMembers();
}
以上代码将产生如下输出:
["1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar"]
["100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "f193.Baz", "f193.Baz", "f193.Baz", "f193.Baz", "f193.Baz", "f193.Baz"]
["1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar"]
我期望的是:
["1", "2"]
["100", "200", "300"]
["1", "2"]
为什么会这样?对我来说这看起来像是一个错误,但也许是这种行为的原因?
看代码才知道是因为构造函数是递归调用的。
简单的修复如下:
static if (member != "__ctor") mixin("members ~= to!string(child." ~ member ~ ");\r\n");
有人可以向我解释以下行为吗?
有了这样的基础 class:
abstract class Foo
{
string[] members;
final:
this(this T)(T child)
{
import std.conv : to;
foreach (member; __traits(derivedMembers, T))
{
mixin("members ~= to!string(child." ~ member ~ ");\r\n");
}
}
void printMembers()
{
writeln(members);
}
}
我希望使用传递的子类型的值填充成员。
但是行为真的很奇怪。
数组成员将被无限填充,这基本上会导致程序内存不足。
如果将 mixin 更改为:
mixin("if (members.length < 20) members ~= to!string(child." ~ member ~ ");\r\n");
然后您将能够看到数组是如何填充的,但是这些值对于代码的工作方式没有意义。
用法示例:
class Bar : Foo
{
int baba;
int caca;
this() { baba = 1; caca = 2; super(this); }
}
class Baz : Foo
{
int foo;
int bar;
int baz;
this() { foo = 100; bar = 200; baz = 300; super(this); }
}
void main()
{
auto b = new Bar();
auto a = new Baz();
b.printMembers();
a.printMembers();
b.printMembers();
}
以上代码将产生如下输出:
["1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar"]
["100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "f193.Baz", "f193.Baz", "f193.Baz", "f193.Baz", "f193.Baz", "f193.Baz"]
["1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar"]
我期望的是:
["1", "2"]
["100", "200", "300"]
["1", "2"]
为什么会这样?对我来说这看起来像是一个错误,但也许是这种行为的原因?
看代码才知道是因为构造函数是递归调用的。
简单的修复如下:
static if (member != "__ctor") mixin("members ~= to!string(child." ~ member ~ ");\r\n");