语言D;结构,不可变数据和怪异错误

问题描述

|| 我正在学习语言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一切正常。 所以,终于我知道我不能为结构属性使用不可变的变量,但是我不明白为什么。     

解决方法

放弃字段的“ 4”个限定词
public struct Vector2d {

    private real _x;
    private real _y;

    this(in real x,in real y) {
        _x = x; _y = y;
    }
    //...
const
是不必要的,它将使您无法进行简单的分配:
Vector2d v;
v = Vector2d(0,0);
这不会编译 并记住,泛型函数(
opBinary
opUnary
)仅在语法分析时才在语法上进行测试,而不是代码的正确性(tested9ѭ返回
Vector!T
,但
T
泛型类型从未声明(因而未定义),但此编译通过...) 编辑我用运算符重载创建了自己的结构,除了
opCmp
opEquals
之外,我仅对
const
的参数不使用
ref const
in
也是如此) edit2我发现最容易将结构理解为可以同时声明,分配和使用的变量组,并在该组变量周围定义了一些额外的功能 因此原始代码中的
Vector2D v;
将被翻译为
const real v__x; const real v__y;
赋值
v = Vector(0,0);
将被(在构造函数内联之后)被翻译为
v__x = 0;v__y = 0;
但是由于v__x被声明为
const
,因此不允许     ,我试图将
dir()
的正文改写为
Vector2d v = Vector2d(0,0);
return v;
然后看到一个不错的错误消息:   vector2D.d(67):错误:变量vector2D.Vector2d.dir.v无法使用不可变成员修改结构   vector2D.d(67):错误:转义对局部变量v的引用 我不了解变量如何修改结构,但这给了我提示:为什么将_x和_y定义为const?我已经从他们的声明中删除了const,并且已经编译了:)     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...