函数参数:“ ref”关键字还是D中的指针?

时间:2018-08-25 17:28:33

标签: d

我目前正在学习D,并且看到它允许以与C ++几乎相同的方式定义指针,但是,它还允许通过ref关键字进行引用传递。关于函数参数,我有以下问题:

  1. 是否可以完全在D中定义函数参数而不使用指针?如果是这样,一般而言,最佳做法是什么?我的理解是ref关键字的目的是消除必须将函数输入参数定义为指针的情况。

  2. 在任何情况下,即使问题1的答案为“是”,在函数中使用指针而不是“ ref”关键字还是更有优势的吗?

例如,以下两个代码产生相同的结果。除了使用“ ref”关键字更方便之外,一个比另一个更好吗?

代码1(使用指针):

import std.stdio;

struct X {
    int s;
    int y;
}

pure void my_func(X *x) {
    x.s = 10;
    x.y = 90;
}

void main() {
   X cat = X(1,2);
   X *cat_ptr = &cat;
   writeln(cat.y);
   my_func(cat_ptr);
   writeln(cat.y);
}

代码2(使用“ ref”关键字):

import std.stdio;

struct X {
    int s;
    int y;
}

pure void my_func(ref X x) {
    x.s = 10;
    x.y = 90;
}

void main() {
   X cat = X(1,2);
   writeln(cat.y);
   my_func(cat);
   writeln(cat.y);
}

我主要来自Java背景,因此我对这些概念的理解不是很好。

1 个答案:

答案 0 :(得分:2)

我发现很少在D中看到原始指针。对于数组,您可以使用切片(例如int[])。要通过引用传递某些内容,您可以将其声明为ref参数。您可以在适合的地方使用类,并使用RefCounted,它实际上是一个智能指针。

D中最常见的指针替换可能是切片(并且在许多方面,指针都可以视为包含零个或一个元素的切片)。也就是说,如果您不考虑this,它实际上也是一个指针。

D的切片只是指针的薄包装,因此您基本上可以对它们执行完全相同的操作,但是使用切片的常规操作更安全。权衡因素是它的速度要慢得多,因为元素访问是经过范围检查的。

由于您说过您来自Java背景,因此我将添加您通常可以用D编写几乎完全相同的代码,并且它将编译和运行,并执行与Java中完全相同的操作。它不是惯用的D,但可以使用。

更新,因为问题已更改:

在示例代码中,没有理由在ref参数上使用指针-它应编译为完全相同的机器代码。通常,只有在要执行指针算术时才应使用指针。如果您不确定要这么做,那就假设您不会。