mirror of https://github.com/sunface/rust-course
				
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
					
						
							1.7 KiB
						
					
					
				
			
		
		
	
	
							1.7 KiB
						
					
					
				the type parameter T is not constrained by the impl trait
use std::default::Default;
trait Maker {
    type Item;
    fn make(&mut self) -> Self::Item;
}
struct Foo<T> {
    a: T,
}
struct Bar;
impl<T> Maker for Bar
    where T: Default  {
    type Item = Foo<T>;
    fn make(&mut self) -> Foo<T> {
        Foo {
            a: <T as Default>::default(),
        }
    }
}
上面的代码会导致以下编译错误:
tests/lang.rs:1000:10: 1000:11 error: the type parameter `T` is not constrained by the impl trait, self type, or predicates [E0207]
tests/lang.rs:1000     impl<T> Maker for Bar
可以使用幽灵数据来初步解决
use std::marker::PhantomData;
struct Bar<T> {
    _m: PhantomData<T>
}
impl<T> Maker for Bar<T>
    where T: Default  {
    type Item = Foo<T>;
    fn make(&mut self) -> Foo<T> {
        Foo {
            a: <T as Default>::default(),
        }
    }
}
关于这个问题,主要是因为在impl代码块中,关联类型是由Self和所有输入类型参数一同决定的,也就是说关联类型中出现的泛型参数,必须在impl中有所定义,要么为Maker增加泛型变量,要么为Bar增加。
如果你想要让Self拥有多种可能的类型,就得使用外部输入的类型参数,而不是关联类型:
use std::default::Default;
trait Maker<Item> {
    fn make(&mut self) -> Item;
}
struct Foo<T> {
    a: T,
}
struct Bar;
impl<T> Maker<Foo<T>> for Bar
    where T: Default  
{
    fn make(&mut self) -> Foo<T> {
        Foo {
            a: <T as Default>::default(),
        }
    }
}
类似的例子还有这个:https://www.reddit.com/r/rust/comments/r61l29/generic_impl_doesnt_work_while_generic_function/