rust - 如何在递归 std::ops::Deref 上绑定类型?
问题描述
我想根据可以通过 deref 强制访问的函数来绑定类型。问题是对 Deref 的限制仅适用于一级强制。
struct A {}
impl A {
fn foo(&self) {
println!("foo");
}
}
struct B {}
impl Deref for B {
type Target = A;
fn deref(&self) -> &Self::Target {
&A{}
}
}
struct C {}
impl Deref for C {
type Target = B;
fn deref(&self) -> &Self::Target {
&B{}
}
}
fn call_with_ref(obj: &A) {
print!("call_with_ref: ");
obj.foo();
}
fn checked_call_with_ref(obj: &A) {
let ptr: *const A = obj;
if !ptr.is_null() {
print!("checked_call_with_ref: ");
obj.foo();
} else {
println!("checked_call_with_ref: null")
}
}
fn call_with_pointer<T: Deref<Target = A>>(ptr: *const T) {
if !ptr.is_null() {
print!("call_with_pointer: ");
unsafe { (*ptr).foo() };
}
}
fn main() {
let c = C{};
let ref_to_c = &c;
let mut ptr_to_c: *const C = ref_to_c;
ref_to_c.foo(); // works
call_with_ref(ref_to_c); // works
// call_with_pointer(ptr_to_C); // does not work bec. it derefs to B
unsafe { checked_call_with_ref(&*ptr_to_c) }; // works on non-nulls
ptr_to_c = std::ptr::null();
unsafe { checked_call_with_ref(&*ptr_to_c) }; // undefined behavior on null pointers
// have to put null check on each call site
if let Some(ref_to_obj) = unsafe { ptr_to_c.as_ref() } {
call_with_ref(ref_to_obj);
}
}
这里的 foo 函数仅由A
. Refs toB
可以通过直接强制调用它,而 refs toC
仍然可以通过 deref-ing 到 B 调用它。Deref<Target = A>
不是作为C
implements的正确绑定Deref<Target = B>
。Rust 有什么Coercible
特点吗?
解决方案
Deref
编译器会自动应用强制转换,因此很少有任何理由将其设为显式绑定。只写call_foo
接受&A
。
fn call_foo(obj: &A) {
print!("Call from fn: ");
obj.foo();
}
也可以看看
推荐阅读
- django - Django 模型自相关子级别
- node.js - 无法将打字稿类正确加载到反应项目中
- pandas - 为什么 Pandas DataFrame 组或切片会过时?它们是副本吗?
- javascript - Javascript可以被欺骗相信一个对象是一个数组吗?
- react-native - 未能分配 14745612 字节分配,其中 7913456 可用字节和 7MB 直到 OOM...目标足迹...增长限制
- image - Webpack 5:sass 找不到图像的路径
- r - 如何使用 Boruta 输出快速有效地从 R 中的 glm 中排除变量
- android - 在协程范围内调试时丢失对局部变量的引用
- django - Django Rest Framework - 我有使用 curl 命令的 API,如何更改它以使用浏览器中的标准 http 请求?
- r - R - 组合两个字符向量,然后切断最后一个字符