【发布时间】:2022-12-03 21:37:42
【问题描述】:
我正在用 Rust 开发一个简单的 opengl 包装器库。
我使用 nalgebra_glm crate 进行数学运算。许多类型都实现了 AsRef 以访问底层数组。我为匹配常见矩阵大小的数组类型手动实现了 Uniform,如 [[T; 4]; 4]、[T; 16]、[T; 3] 等。
所以我可以通过调用 Box::new(<nalgebra_glm matrix or vector>.as_ref().clone()) 获得一个新的 Box<dyn Uniform> 但它不必要地冗长。
我想创建一个方便的函数,将任何 &[T](即 Clone 和 AsRef)转换为实现 Uniform 的某种类型 U 到 Vec<Box<dyn Uniform>>。类似于 ToOwned 特征。
这是我想出的。
pub trait Uniform {
fn bind(&self, location: GLint);
}
pub fn to_owned<U: Uniform + Clone, T: AsRef<U>>(uniforms: &[T]) -> Vec<Box<dyn Uniform>>
where Vec<Box<dyn Uniform>>: FromIterator<Box<U>>
{
uniforms.into_iter()
.map(AsRef::as_ref)
.map(Clone::clone)
.map(Box::new)
.collect()
}
但是当我尝试在以下上下文中使用此函数时,它导致了我难以理解的错误。
perspective_matrix() 和view_matrix() 都是Mat4 类型并提供AsRef<[[f32; 4]; 4]。
let common_uniforms = to_owned(&[camera.perspective_matrix(), camera.view_matrix()]);
error[E0277]: the trait bound `(dyn Uniform + 'static): Clone` is not satisfied
--> src\main.rs:167:27
|
167 | let common_uniforms = to_owned(&[camera.perspective_matrix(), camera.view_matrix()]);
| ^^^^^^^^ the trait `Clone` is not implemented for `(dyn Uniform + 'static)`
|
note: required by a bound in `uniform::to_owned`
--> src\uniform.rs:9:30
|
9 | pub fn to_owned<U: Uniform + Clone, T: AsRef<U>>(uniforms: &[T]) -> Vec<Box<dyn Uniform>>
| ^^^^^ required by this bound in `uniform::to_owned`
为什么生成的特征对象需要 Clone? clone 仅在通用 U 操作期间需要,因此只有 U 应实现 Clone。为什么它与最终特征对象有任何关系?我希望因为U实现了Uniform,所以应该可以从中创建一个dyn Uniform特征对象。
此外,我不能要求 Clone 作为 Uniform 的超级特征,因为它会使它不安全。
我已经尝试将结果框类型显式转换为 trait 对象,添加 'static lifetime bound 但无济于事。
pub fn to_owned<U: 'static + Uniform + Clone, T: AsRef<U>>(uniforms: &[T]) -> Vec<Box<dyn Uniform>>
where Vec<Box<dyn Uniform>>: FromIterator<Box<U>>
{
uniforms.into_iter()
.map(AsRef::as_ref)
.map(Clone::clone)
.map(|uniform| Box::new(uniform) as Box<dyn Uniform>)
.collect()
}
我真的不明白我的代码有什么问题。要么是我犯了一些句法错误,要么是我在这里试图完成的事情存在更深层次的逻辑错误。
我将不胜感激任何帮助。
【问题讨论】:
-
你的代码片段真的不是完整的minimal reproducible example,提供一个虚拟的
camera和适当的uses 外部类型(GLint,Mat4?,...)所以我们可以运行你的例如,我们自己查看错误并处理它。
标签: rust