给定一个带有u32
字段的结构体。它只有一个重载的方法,可以用作该字段的设置器和获取器。
pub struct Struct {
value: u32
}
pub trait Trait<T> {
fn method(&mut self, arg: T);
}
impl Trait<u32> for Struct {
fn method(&mut self, arg: u32) {
self.value = arg;
}
}
impl Trait<&mut u32> for Struct {
fn method(&mut self, arg: &mut u32) {
*arg = self.value;
}
}
这个结构的一个可能用途如下:
fn main() {
let mut s = Struct { value: 0 };
let mut v = 0;
s.method(&mut v);
println!("The value of s is: {}", v);
s.method(3);
s.method(&mut v);
println!("The value of s is: {}", v);
}
在使用结构体作为 ffi 接口时,调用重载方法而非直接访问字段的优点有两个。一方面,该方法仍然可以修改值,例如先将
&str
转换为 CString
,然后将 *const u8
存储为值,这使字符串可用于 C。另一方面,重载该方法还使得在 C 中可以使用给定的名称,而不是编写 setValue
和 getValue
,例如。然而,正如您在此处所见,其中一个方法不需要对 self 进行可变引用,因为它不会更改值字段,但由于特性需要,无论哪种情况都会使用它。该结构体不仅被配置然后用作 ffi 方法的参数,还可以作为该方法的返回值出现,在这种情况下,它将作为不可变引用返回,并且只能从中读取。自定义的特性实现将如下所示。impl Trait<u32> for Struct {
fn method(&mut self, arg: u32) {
self.value = arg;
}
}
impl Trait<&mut u32> for Struct {
fn method(&self, arg: &mut u32) {
*arg = self.value;
}
}
显然,这里无法工作,因为第二个实现块的方法签名与trait不同。我已经尝试使用arbitrary_self_types
功能将self参数定义为trait中的另一个通用参数,但不幸的是,这并没有起作用。
let s = Struct { value: 0 }; let mut v = 0; s.method(&mut v); println!("The value of s is: {}", v); } 而不破坏 fn main() {
let mut s = Struct { value: 0 }; s.method(34); } - Goldenprime