隐藏和接收通用 T 对象
Hiding and receiving generic T objects
给出以下 Rust 代码:
struct Wrapper<T> {
data: Vec<T>, // more attributes...
}
trait DataWrapper<T> {
fn get_column(&self) -> &Vec<T>;
fn get_data(&self, row: usize) -> &T;
}
impl<T> DataWrapper<T> for Wrapper<T> {
fn get_column(&self) -> &Vec<T> {
&self.data
}
fn get_data(&self, row: usize) -> &T {
&self.data[row]
}
}
struct Inter<T> {
inter_value: Wrapper<T>,
}
trait GetInter {
fn get_count(&self) -> &str;
}
impl GetInter for Inter<i32> {
fn get_count(&self) -> &str {
"i32"
}
}
impl GetInter for Inter<f64> {
fn get_count(&self) -> &str {
"f64"
}
}
fn create_vector() -> Vec<Box<GetInter>> {
// Add some sample data
let x = Wrapper { data: vec![1, 2, 3] };
let y = Wrapper { data: vec![1.1, 2.2, 3.3] };
let mut vec: Vec<Box<GetInter>> = Vec::new();
let m = Inter { inter_value: x };
let m = Box::new(m);
let m = m as Box<GetInter>;
vec.push(m);
let n = Inter { inter_value: y };
let n = Box::new(n);
let n = n as Box<GetInter>;
vec.push(n);
vec
}
struct ColumnWrapper {
columns: Vec<Box<GetInter>>, // more attributes
}
fn create_column_wrapper() -> ColumnWrapper {
let result = create_vector();
ColumnWrapper { columns: result }
}
fn main() {
let result = create_column_wrapper();
for iter1 in result.columns {
println!("1: {}", iter1.get_count());
}
}
Wrapper<T>
存储一个通用的 Vec
,详细地存储列存储中的一个数据列。相应的实现returns Vec
或具体元素作为参考。
Inter<T>
和 GetInter
特征的想法是隐藏通用 T
对象,它来自 Wrapper 的 Vec<T>
通用数据类型。 get_count()
方法仅用于测试目的。
create_vector()
使用一些示例数据创建两个新的 Vec
。结果被转换为 GetInter
,包装成 Box
并存储在 Vec<Box<GetInter>>
中。最后,调用者将创建一个新的 ColumnWrapper
元素。现在给出了通用数据表示。
编译后运行给出正确的结果:
i32
f64
现在真正的问题开始了。我尝试访问存储在 Wrapper<T>
中的原始数据。
我的第一个想法是使用 Rust 的动态调度功能。它应该在运行时检测真实的数据类型。
main()
函数修改:
fn main() {
let result = create_column_wrapper();
for iter1 in result.columns {
println!("1: {}", iter1.get_count());
for iter2 in dyn_dispatch(*iter1) {
println!("2: {}", iter2);
}
}
}
对应的未测试dyn_dispatch()
函数:
trait Foo<T> {
fn method(x: &Inter<T>) -> &Vec<T>;
}
impl<i32> Foo<i32> for Inter<i32> {
fn method(x: &Inter<i32>) -> &Vec<i32> {
&x.inter_value.data
}
}
impl<f64> Foo<f64> for Inter<f64> {
fn method(x: &Inter<f64>) -> &Vec<f64> {
&x.inter_value.data
}
}
fn dyn_dispatch<T>(x: &GetInter) -> &Vec<T> {
Foo::method(&x as &Inter<T>)
}
编译失败并抛出错误:
85:2 error: conflicting implementations of trait Foo<_>
for type Inter<_>
: [E0119]
知道如何修复编译错误或其他错误以及 更多 隐藏和访问通用 T
对象的简单想法吗?
这里有几个问题。
第一个错误:
error: conflicting implementations of trait Foo<> for type Inter<>:
[E0119]
其实指的是这些:
impl<i32> Foo<i32> for Inter<i32> { ... }
impl<f64> Foo<f64> for Inter<f64> { ... }
因为 i32
和 f64
是参数,它们都等同于:
impl<T> Foo<T> for Inter<T> { ... }
也就是说,Foo<T>
对于 Inter<T>
对于任何 T 的实现因此是相互冲突的实现。解决方法是将它们写成:
impl Foo<i32> for Inter<i32> { ... }
下一个问题是您实际上并没有进行动态调度。您的 dyn_dispatch
函数必须在编译时指定或推断出 T
;它不能每次 return 不同的类型;同样,您不能像那样从 GetInter
向下转换为 Inter<T>
。您需要按照与 GetInter::get_count
.
相同的方式进行操作
给出以下 Rust 代码:
struct Wrapper<T> {
data: Vec<T>, // more attributes...
}
trait DataWrapper<T> {
fn get_column(&self) -> &Vec<T>;
fn get_data(&self, row: usize) -> &T;
}
impl<T> DataWrapper<T> for Wrapper<T> {
fn get_column(&self) -> &Vec<T> {
&self.data
}
fn get_data(&self, row: usize) -> &T {
&self.data[row]
}
}
struct Inter<T> {
inter_value: Wrapper<T>,
}
trait GetInter {
fn get_count(&self) -> &str;
}
impl GetInter for Inter<i32> {
fn get_count(&self) -> &str {
"i32"
}
}
impl GetInter for Inter<f64> {
fn get_count(&self) -> &str {
"f64"
}
}
fn create_vector() -> Vec<Box<GetInter>> {
// Add some sample data
let x = Wrapper { data: vec![1, 2, 3] };
let y = Wrapper { data: vec![1.1, 2.2, 3.3] };
let mut vec: Vec<Box<GetInter>> = Vec::new();
let m = Inter { inter_value: x };
let m = Box::new(m);
let m = m as Box<GetInter>;
vec.push(m);
let n = Inter { inter_value: y };
let n = Box::new(n);
let n = n as Box<GetInter>;
vec.push(n);
vec
}
struct ColumnWrapper {
columns: Vec<Box<GetInter>>, // more attributes
}
fn create_column_wrapper() -> ColumnWrapper {
let result = create_vector();
ColumnWrapper { columns: result }
}
fn main() {
let result = create_column_wrapper();
for iter1 in result.columns {
println!("1: {}", iter1.get_count());
}
}
Wrapper<T>
存储一个通用的 Vec
,详细地存储列存储中的一个数据列。相应的实现returns Vec
或具体元素作为参考。
Inter<T>
和 GetInter
特征的想法是隐藏通用 T
对象,它来自 Wrapper 的 Vec<T>
通用数据类型。 get_count()
方法仅用于测试目的。
create_vector()
使用一些示例数据创建两个新的 Vec
。结果被转换为 GetInter
,包装成 Box
并存储在 Vec<Box<GetInter>>
中。最后,调用者将创建一个新的 ColumnWrapper
元素。现在给出了通用数据表示。
编译后运行给出正确的结果:
i32
f64
现在真正的问题开始了。我尝试访问存储在 Wrapper<T>
中的原始数据。
我的第一个想法是使用 Rust 的动态调度功能。它应该在运行时检测真实的数据类型。
main()
函数修改:
fn main() {
let result = create_column_wrapper();
for iter1 in result.columns {
println!("1: {}", iter1.get_count());
for iter2 in dyn_dispatch(*iter1) {
println!("2: {}", iter2);
}
}
}
对应的未测试dyn_dispatch()
函数:
trait Foo<T> {
fn method(x: &Inter<T>) -> &Vec<T>;
}
impl<i32> Foo<i32> for Inter<i32> {
fn method(x: &Inter<i32>) -> &Vec<i32> {
&x.inter_value.data
}
}
impl<f64> Foo<f64> for Inter<f64> {
fn method(x: &Inter<f64>) -> &Vec<f64> {
&x.inter_value.data
}
}
fn dyn_dispatch<T>(x: &GetInter) -> &Vec<T> {
Foo::method(&x as &Inter<T>)
}
编译失败并抛出错误:
85:2 error: conflicting implementations of trait
Foo<_>
for typeInter<_>
: [E0119]
知道如何修复编译错误或其他错误以及 更多 隐藏和访问通用 T
对象的简单想法吗?
这里有几个问题。
第一个错误:
error: conflicting implementations of trait Foo<> for type Inter<>: [E0119]
其实指的是这些:
impl<i32> Foo<i32> for Inter<i32> { ... }
impl<f64> Foo<f64> for Inter<f64> { ... }
因为 i32
和 f64
是参数,它们都等同于:
impl<T> Foo<T> for Inter<T> { ... }
也就是说,Foo<T>
对于 Inter<T>
对于任何 T 的实现因此是相互冲突的实现。解决方法是将它们写成:
impl Foo<i32> for Inter<i32> { ... }
下一个问题是您实际上并没有进行动态调度。您的 dyn_dispatch
函数必须在编译时指定或推断出 T
;它不能每次 return 不同的类型;同样,您不能像那样从 GetInter
向下转换为 Inter<T>
。您需要按照与 GetInter::get_count
.