我想在 D 中创建一个像这样工作的向量结构:
vec u, v;
vec w = [2,6,8];
v.x = 9; // Sets x
v[1] = w.y; // Sets y
u = v; // Should copy data
稍后我还想添加
u = v * u
之类的内容等等,但上述内容现在就可以了。这就是我已经走了多远:
struct vec3f
{
float[3] data;
alias data this;
@property
{
float x(float f) { return data[0] = f; }
float y(float f) { return data[1] = f; }
float z(float f) { return data[2] = f; }
float x() { return data[0]; }
float y() { return data[1]; }
float z() { return data[2]; }
}
void opAssign(float[3] v)
{
data[0] = v[0];
data[1] = v[1];
data[2] = v[2];
}
}
现在这几乎使它像我想要的那样工作,但我不确定这是否“正确”。 opAssign() 是否应该返回一些值?
我也想知道这是否真的尽可能快?我是否尝试过添加
alias data[0] x;
等等,但这不起作用。有任何想法吗?或者这是“它是如何完成的”?也许编译器足够聪明,可以确定属性函数或多或少是别名?
最佳答案
总的来说,这看起来很合理。出于赋值链的目的,opAssign 可以说应该返回 v。但是,在实践中,这经常被忽略并且可能会导致性能下降(我不知道)。与 D1 不同,您可以从 D2 中的函数返回静态数组。
就性能而言,考虑这一点的最佳方法是在装配级别。假设启用内联,x()
几乎肯定会被内联。静态数组直接存储在结构中,无需额外的间接层。指令return data[0];
将导致编译器生成代码以从结构开头的偏移量读取。这个偏移量将在编译时知道。因此,最有可能调用x()
将生成与 x
完全相同的汇编指令实际上是一个公共(public)成员变量。
但是,另一种可能性是使用匿名联合和结构:
struct vec3f
{
union {
float[3] vec;
struct {
float x;
float y;
float z;
}
}
alias vec this; // For assignment of a float[3].
}
请注意,尽管
alias this
现在有相当多的错误,除非您愿意提交一些错误报告,否则您可能不应该使用它。
关于struct - 允许在 D 中进行 [i] 和 .xyz 操作的快速向量结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3098242/