我目前正在学习D,并且看到它允许以与C ++几乎相同的方式定义指针,但是,它还允许通过ref关键字进行引用传递。关于函数参数,我有以下问题:
是否可以完全在D中定义函数参数而不使用指针?如果是这样,一般而言,最佳做法是什么?我的理解是ref关键字的目的是消除必须将函数输入参数定义为指针的情况。
在任何情况下,即使问题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背景,因此我对这些概念的理解不是很好。
答案 0 :(得分:2)
我发现很少在D中看到原始指针。对于数组,您可以使用切片(例如int[]
)。要通过引用传递某些内容,您可以将其声明为ref
参数。您可以在适合的地方使用类,并使用RefCounted
,它实际上是一个智能指针。
D中最常见的指针替换可能是切片(并且在许多方面,指针都可以视为包含零个或一个元素的切片)。也就是说,如果您不考虑this
,它实际上也是一个指针。
D的切片只是指针的薄包装,因此您基本上可以对它们执行完全相同的操作,但是使用切片的常规操作更安全。权衡因素是它的速度要慢得多,因为元素访问是经过范围检查的。
由于您说过您来自Java背景,因此我将添加您通常可以用D编写几乎完全相同的代码,并且它将编译和运行,并执行与Java中完全相同的操作。它不是惯用的D,但可以使用。
更新,因为问题已更改:
在示例代码中,没有理由在ref参数上使用指针-它应编译为完全相同的机器代码。通常,只有在要执行指针算术时才应使用指针。如果您不确定要这么做,那就假设您不会。