【发布时间】:2011-05-26 09:04:18
【问题描述】:
我正在学习语言 D。我的第一次尝试是一个简单的 2d 矢量,我可以添加、减去、点积等... 当我尝试编译时出现此错误:
错误:
错误:(Vector2d __ctmp1245 = D4math2v28Vector2d6_initZ; , __ctmp1245).this(this._x / l,this._y / l) 不可变
注意:错误与 Vector2d.dir() 相关
代码是:
import std.math;
public struct Vector2d {
private const real _x;
private const real _y;
this(in real x, in real y) {
_x = x; _y = y;
}
// Basic Properties ***************************************
@property const real X () { return _x; }
@property const real Y () { return _y; }
@property const real length () { return sqrt(_x*_x + _y*_y); }
// Operations ***************************************
/**
* Define Equality
*/
const bool opEquals(ref const Vector2d rhs) {
return approxEqual(_x, rhs._x) && approxEqual(_y, rhs._y);
}
/**
* Define unary operators + and - (+v)
*/
ref Vector2d opUnary(string op)() const
if (op == "+" || op == "-")
{
return Vector2d(mixin(op~"_x"), mixin(op~"_y"));
}
/**
* Define binary operator + and - (v1 + v2)
*/
ref Vector2d opBinary(string op) (ref const Vector2d rhs)
if (op == "+" || op == "-")
{
return Vector2d(mixin("_x" ~ op ~ "rhs._x"),mixin("_y" ~ op ~ "rhs._y"));
}
/**
* Scalar multiplication & division (v * 7)
*/
ref Vector2d opBinary(string op) (ref const real rhs) const
if (op == "*" || op == "/")
{
return Vector2d(mixin("_x" ~ op ~ "rhs"),mixin("_y" ~ op ~ "rhs"));
}
/**
* Dot Product (v1 * v2)
*/
ref real opBinary(string op) (ref const Vector2d rhs) const
if (op == "*") {
return _x*rhs._x + _y*rhs._y;
}
/**
* Obtain the director vector of this vector.
*/
ref Vector2d dir() const {
auto l = this.length();
return Vector2d(_x / l, _y /l);
}
/**
* Obtains the projection of this vector over other vector
* Params:
* b = Vector over project this vector
*/
ref Vector2d projectOnTo(in Vector2d b) const {
return b.dir() * (this * b.dir());
}
}
我不明白为什么会出现此错误。另外我尝试更改类型限定符不成功。 如果我尝试这个,即使我得到同样的错误:
ref Vector2d dir() const {
auto l = this.length();
return Vector2d(2,3);
}
编辑:
我尝试从属性中删除“const”并从点积中删除“ref”(我得到的建议不是左值)。现在的错误是这样的:
src/math/v2.d(82): 错误:this.opBinary(b.dir()) 不是左值
第 82 行是:
return b.dir() * (this * b.dir());
自动回答:
我修复了最后一个错误,我更改了 ProjectOnTo 对此:
ref Vector2d projectOnTo(in Vector2d b) const {
auto a = this * b.dir();
return b.dir() * a;
}
另外我运行了一个单元测试,看起来 Vector2d 运行良好。
所以,我现在终于知道我不能将不可变变量用于结构属性,但我不明白为什么。
【问题讨论】:
-
您可以尝试在返回类型中删除
ref吗? -
顺便问一下,您使用哪个编译器?
-
@xs0,删除 ref 确实有帮助,但是......它看起来像一个编译器错误,在 ref 之前几行并且没有投诉...
-
那是因为编译器只对模板进行语法控制(包括运算符重载函数),如果你添加一个
unittest{Vector2d v;v+v;},它会抱怨它然后 -
@xs0 从 dir() 中删除“ref”和“const”不会改变任何东西,同样的错误。
标签: immutability d