2014-12-04 50 views
2

锈色程序,我其中我想打印一个数字,或数字的管分隔矢量,因此该简单的包装枚举的使用情况:匹配参数化类型中锈病

pub enum OneOrMore<T> { 
    One(T), 
    More(Vec<T>) 
} 

其工作正常。但后来我想格式逻辑搬进OneOrMore类型,所以我尝试:

impl<T: Show> Show for OneOrMore<T> { 
    fn fmt(&self, f: &mut Formatter) -> Result { 
    match self { 
     One(x) => x.fmt(f), 
     More(xs) => /* vec_join(xs, "|") or whatever */, 
    } 
    } 
} 

由于impl是参数,它期待One<T>但我的代码描述One<_>。问题是我无法弄清楚在哪里把类型参数放在匹配武器里面。 syntax guide未给出参数化类型匹配的示例,fmt本身不接受类型参数,并且所有盲目猜测(One(x: T),One<T>(x)等)都不是有效的Rust。任何想法,我应该指出的比赛武器的类型?

回答

4

match表达式中,self的类型为&OneOrMore<T>,但臂图案的类型为OneOrMore<T>;即你在引用上相匹配,但武器不是引用。

你可以改变模式,以引用:

impl<T: Show> Show for OneOrMore<T> { 
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { 
    match self { 
     &One(ref x) => x.fmt(f), 
     &More(ref xs) => /* ... */, 
    } 
    } 
} 

或者你可以避免提领self,而不是重复&

impl<T: Show> Show for OneOrMore<T> { 
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { 
    match *self { 
     One(ref x) => x.fmt(f), 
     More(ref xs) => /* ... */, 
    } 
    } 
} 

注意,在这两种情况下,我们需要添加ref关键字xxs绑定来创建参考OneOrMore的内部。换句话说,没有refxxs将是T类型;与ref,他们是类型&T。如果没有ref,编译器会抱怨我们试图将一个值从OneOrMore中移出,这是不允许借用的。

+0

谢谢,我这次完全误解了编译器错误。 – bees 2014-12-04 04:37:29

+4

顺便说一下,标准的锈风格是'match * foo {Bar =>()}',而不是'match foo {&Bar =>()}',尽管如果匹配的表达式是一个元组,如'match(self,other){(&Foo,&Foo)=>()}'。 – 2014-12-04 06:55:20