自动引用与解引用:Rust 与 C++ 的一点小对比
在关于引用的话题上,C++ 与 Rust 选择了不同的策略来方便编写代码。以前我只会写一点 C++,只有片面的认识。现在我在 Rust 中遇到了不一样的设计,由此深化了对个中选择的理解。
现在的问题是:
要不要给函数调用的参数加上自动引用与解引用的功能?
要解决这个问题,先概览一下 Rust 和 C++ 的相关机制。
Rust 与 C++ 中的引用机制
Rust 和 C++ 都实现了一定程度上的自动引用与自动解引用(automatic referencing and dereferencing):
C++
在 C++ 中,引用类型可以「完全自动」地解引用,而指针类型没有任何自动功能。
auto a = some_val;   // copy
auto& b = a;         // reference
auto* c = &some_val; // Another sort of reference, namely the *pointer*.
b += a;    // `b` auto-dereferenced to the original value, equivalent to `a += a;`
*c += a;   // pointers do not have auto-dereference support.
b.some_method();    // 'b' is again auto-dereferenced to a
(*c).some_method();
为了提供方便,指针类型多了一个 -> 运算符,可以把解引用操作和访问成员的操作合并。
c->some_method();
Rust
在 Rust 中,只有调用成员函数的时候才会有自动引用与解引用,其它操作里没有,作为参数的时候也没有:
let val = some_val;
let my_ref = &val; // Get a reference to val.
my_ref.some_method();   // Only auto-deref in method calls or when visiting members.
let mut a = 1;
let mut b = &a;
*b += 1; // **No** auto-deref otherwise.
fn my_func(arg: &i32) { ... } // This function receives a reference to an i32.
my_func(&a); // No auto referencing in arguments.
引用在函数调用中的问题
之前我在看 Google 的编程规范时,注意到其中要求 C++ 函数的参数不能是可变引用(即 &arg),只能是下面几种:
void my_func(
    MyType copied,
    MyType const& immutably_referenced,
    MyType *pointer_referenced
);
其理由是为了避免混淆。如果允许可变引用,由于在 C++ 中引用的过程是自动完成的(不需要加上取引用符,那样得到的是指针),函数的调用者将不得不去检查函数声明才能得知参数是否会被改变。比如下面的例子中,我必须要去查找 some_external_function 的原型才能知道我的参数会不会被改变。
some_external_function( my_val_which_I_dont_want_it_to_change );
good_func( &my_val_which_I_want_you_to_change );

                
            
        
浙公网安备 33010602011771号