在D语言中不能通过引用传递

时间:2013-11-16 15:12:48

标签: reference pass-by-reference d

我在类testclass

中有一个构造函数
@safe public nothrow this(ref Socket socket) {
    // Inside class modulename.classname
    this.socket = socket;
}

但是当我在main方法中初始化这种类型的对象时,我遇到了一些编译错误。

void main() {
    auto variablename = new modulename.classname(
        cast(Socket) new TcpSocket() // main.d line 5
    );
}

错误:

main.d(5): Error: constructor testmodule.testclass.this (ref 
Socket socket) is not callable using argument types (Socket)
main.d(5): Error: no constructor for testclass

为什么我不能通过引用传递套接字?

3 个答案:

答案 0 :(得分:7)

你不需要通过ref传递类

默认情况下通过引用保存类(以避免继承时出现切片问题),因此无论如何你只是在两种情况下传递指针

代码中的问题是cast(Socket) new TcpSocket()是一个无法分配的rvalue,因此无法通过ref传递

答案 1 :(得分:2)

接受的答案在陈述中不正确:

  

您不需要通过ref传递类
  默认情况下,类通过引用保留

类是引用类型,但是对类的引用通过值作为方法参数传递给。仅当您修改参考所指的内容时,此功能才起作用。

例如,修改类成员的通常情况适用于以下两种方式:

import std.stdio;

class K {
    int i;   
}

void main()
{
    auto k = new K();
    k.i = 3;
    NonRef(k);
    writeln(k.i);    // Writes 5

    k.i = 3;
    ByRef(k);
    writeln(k.i);    // Writes 5
}

void NonRef(K k) {
    k.i = 5;
}

void ByRef(ref K k) {
    k.i = 5;
}

但是,请考虑以下问题:

import std.stdio;

class K {
    int i;   
}

void main()
{
    auto k = new K();
    k.i = 3;
    NonRef(k);
    writeln(k.i);    // Writes 3 !

    k.i = 3;
    ByRef(k);
    writeln(k.i);    // Writes 0 !
}

void NonRef(K k) {
    k = new K();
}

void ByRef(ref K k) {
    k = new K();
}

关于您的问题,在回答此问题时,D仍然不支持ref传递的RValues。我假定这与编译器有关,后者不知道将ref值应用于什么。如您在回答中所做的那样,可以通过创建一个临时变量来轻松克服这一问题。

答案 2 :(得分:0)

我通过在构造函数调用之外初始化Socket来解决问题。我不确定这是不是一个错误,或者语言是故意的。

void main() {
    auto socket = cast(Socket) new TcpSocket();
    auto variablename = new modulename.classname(
        socket
    );
}