简体   繁体   English

无约束类型参数错误

[英]unconstrained type parameter error

I'm trying to interface glium with cgmath. 我正在尝试将glium与cgmath接口。 Following this answer , I have implemented a ToArray trait to convert instances of cgmath::Matrix4 into a format usable by glium: 这个答案之后 ,我实现了一个ToArray特性,将cgmath::Matrix4实例转换为cgmath::Matrix4可用的格式:

pub trait ToArray {
    type Output;
    fn to_array(&self) -> Self::Output;
}

impl<S: cgmath::BaseNum> ToArray for cgmath::Matrix4<S> {
    type Output = [[S; 4]; 4];
    fn to_array(&self) -> Self::Output {
        (*self).into()
    }
}

Since I don't always use Matrix4 directly, I need a similar implementation for cgmath transform types. 由于我并不总是直接使用Matrix4 ,因此我需要一个类似于cgmath转换类型的实现。 For example for cgmath::Decomposed : 例如对于cgmath::Decomposed

impl<S: cgmath::BaseFloat, R: cgmath::Rotation3<S>> ToArray
    for cgmath::Decomposed<cgmath::Vector3<S>, R> {
    type Output = [[S; 4]; 4];
    fn to_array(&self) -> Self::Output {
        cgmath::Matrix4::<S>::from(*self).into()
    }
}

This works, but I'd like to avoid duplicating the code for all transform types, so I thought I would define a generic implementation for anything that can be converted to a Matrix4 : 这有效,但我想避免重复所有转换类型的代码,所以我想我会为可以转换为Matrix4任何东西定义一个通用实现:

impl<S: cgmath::BaseFloat, T: Into<cgmath::Matrix4<S>>> ToArray for T {
    type Output = [[S; 4]; 4];
    fn to_array(&self) -> Self::Output {
        cgmath::Matrix4::<S>::from(*self).into()
    }
}

Unfortunately, this doesn't work: 不幸的是,这不起作用:

error[E0207]: the type parameter `S` is not constrained by the impl trait, self type, or predicates
  --> src/main.rs:23:6
   |
23 | impl<S: cgmath::BaseFloat, T: Into<cgmath::Matrix4<S>>> ToArray for T {
   |      ^ unconstrained type parameter

I have two questions: 我有两个问题:

  • Why doesn't the above code work? 为什么上面的代码不起作用? From reading the rustc --explain output, I would expect the T: Into<cgmath::Matrix4<S>> to act as a valid constraint on S as well as T . 从读取rustc --explain输出,我希望T: Into<cgmath::Matrix4<S>>作为ST的有效约束。
  • How can I write a generic implementation for anything that can be converted into a Matrix4 ? 如何为可以转换为Matrix4任何东西编写通用实现?

Imagine I defined a type like this 1 : 想象一下,我定义了这样的类型1

struct PolymorphicMatrix;

impl Into<cgmath::Matrix4<f32>> for PolymorphicMatrix {
    fn into(self) -> cgmath::Matrix4<f32> {
        cgmath::Matrix4::new(
            1.0, 1.0, 1.0, 1.0,
            1.0, 1.0, 1.0, 1.0,
            1.0, 1.0, 1.0, 1.0,
            1.0, 1.0, 1.0, 1.0)
    }
}

impl Into<cgmath::Matrix4<f64>> for PolymorphicMatrix {
    fn into(self) -> cgmath::Matrix4<f64> {
        cgmath::Matrix4::new(
            2.0, 2.0, 2.0, 2.0,
            2.0, 2.0, 2.0, 2.0,
            2.0, 2.0, 2.0, 2.0,
            2.0, 2.0, 2.0, 2.0)
    }
}

Which of these impls will be used to implement ToArray ? 哪些impls将用于实现ToArray Both are applicable, but you can only implement ToArray once for PolymorphicMatrix , because ToArray has no type parameters. 两者都是适用的,但你只能实现ToArray一次PolymorphicMatrix ,因为ToArray无类型参数。 That's what the error means: it's not valid because it would cause issues in a situation like this. 这就是错误的含义:它无效,因为它会在这种情况下导致问题。

Since you control neither Into nor cgmath::Matrix4 , the only aspect you can change is ToArray . 由于您既不控制Into也不控制cgmath::Matrix4 ,您可以更改的唯一方面是ToArray You can add a type parameter that is not used in the trait definition itself, and implementations can use that type parameter. 您可以添加特征定义本身未使用的类型参数,并且实现可以使用该类型参数。

pub trait ToArray<S> {
    type Output;
    fn to_array(&self) -> Self::Output;
}

impl<S: cgmath::BaseFloat, T: Into<cgmath::Matrix4<S>>> ToArray<S> for T {
    type Output = [[S; 4]; 4];
    fn to_array(&self) -> Self::Output {
        cgmath::Matrix4::<S>::from(*self).into()
    }
}

Naturally, you can't enforce any kind of correlation between S and Output . 当然,您不能在SOutput之间强制执行任何类型的关联。 Also, that type parameter might cause some ambiguities: since it's not used in the trait, the compiler might not be able to infer S from usage in some situations, so you may have to specify it explicitly. 此外,该类型参数可能会导致一些歧义:由于它没有在特征中使用,编译器可能无法在某些情况下从使用中推断出S ,因此您可能必须明确指定它。 If that becomes a problem, you might want to explore using generic-array . 如果这成为问题,您可能想要使用generic-array进行探索。 It would let you lift the array dimensions to type parameters, so that you could get rid of the associated type and instead use the type parameters directly in the return type of to_array , which would help the compiler's inference. 它可以让你将数组维度提升为类型参数,这样你就可以摆脱相关的类型,而是直接在to_array的返回类型中使用类型参数,这将有助于编译器的推理。


1 Normally, one would implement From rather than Into . 1通常,人们会实现From而不是Into I'm using Into here to stay closer to the problem as stated. 我使用Into这里说更贴近的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何解决 Rust 中的这种无约束类型参数错误 - How to solve this unconstrained type parameter error in Rust 实现 IntoIterator 的无约束类型参数 - Unconstrained type parameter implementing IntoIterator 如何避免无约束类型参数错误 - how to avoid unconstrained type paramameter error Rust“无法为此有界类型参数确定类型:无约束类型” - Rust “cannot determine a type for this bounded type parameter: unconstrained type” 嵌套的通用特征参数给出“无约束类型参数” - Nested generic trait parameter gives "unconstrained type parameter" 在另一个特征的特征实现中使用 const generic 会导致“不受约束的 const 参数”错误 - using const generic in implementation of trait for another trait causes "unconstrained const parameter" error 实现Index trait时无约束的生命周期错误 - Unconstrained lifetime error when implementing Index trait 为什么一致性规则会引发错误“类型参数必须用作某些本地类型的类型参数”? - Why do the coherence rules raise the error “the type parameter must be used as the type parameter for some local type”? 错误:类型参数`D`必须用作某些本地类型的类型参数 - error: type parameter `D` must be used as the type parameter for some local type 泛型错误:期望的类型参数,找到结构 - Generics Error: expected type parameter, found struct
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM