Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics 如何匹配泛型结构字段的具体类型?_Generics_Rust - Fatal编程技术网

Generics 如何匹配泛型结构字段的具体类型?

Generics 如何匹配泛型结构字段的具体类型?,generics,rust,Generics,Rust,我在玩lambda演算,但由于我对泛型不太了解,我想确认一下我对某些事情的理解,并解决一个错误。考虑以下定义: pub trait Term {} // a lambda term - a variable, an abstraction or an application pub struct Var(pub usize); // a variable, De Bruijn style pub struct Abs<T: Term>(T); // an abstraction p

我在玩lambda演算,但由于我对泛型不太了解,我想确认一下我对某些事情的理解,并解决一个错误。考虑以下定义:

pub trait Term {} // a lambda term - a variable, an abstraction or an application

pub struct Var(pub usize); // a variable, De Bruijn style
pub struct Abs<T: Term>(T); // an abstraction
pub struct App<T: Term, U: Term>(T, U); // application of T on U
有趣的是,我在这里不需要
App
,但希望到目前为止一切顺利-现在我想为上述结构实现
fmt::Display

use std::fmt;
use std::fmt::Display;

impl fmt::Display for Var {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl<T: Term+Display> Display for Abs<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "λ{}", self.0)
    }
}
但它在以下方面失败了:

错误[E0308]:类型不匹配
-->src\ast.rs:34:8
|
34 |应用程序(Var(|),Var(|))=>写入!(f,“{}{}”,self.0,self.1),
|^应为类型参数,找到结构'ast::Var'`
|
=注意:应为'T'类型`
=注意:找到类型`ast::Var`
我想根据其内容的类型以不同的方式打印
App
。我试图找到一个相关的问题,但它们大多围绕着相关的类型。是否有一个简单的解决方案,或者我必须修改定义

我想根据其内容的类型以不同的方式打印
App

这很简单,只需为您希望能够打印的每种独特类型的
应用程序实现
显示

use std::fmt;

struct App<T, U>(T, U);

impl fmt::Display for App<i32, bool> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Awesome choice!")
    }
}

impl fmt::Display for App<bool, String> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Woah, a string? Really?")
    }
}

fn main() {
    println!("{}", App(42i32, false));
    println!("{}", App(true, "wow".to_string()));
}
这在标准库中有一个近似的模拟:。此类型接受泛型,但所有有趣的功能仅针对少数具体类型实现,如
&[u8]
Vec

但是它仍然会导致问题,例如,对于
App
,因为内部
App
需要再次使用2个类型参数

是的,您必须指定泛型,因为
App
不是一种类型,它只是迈向一种类型的垫脚石

这完全取决于你想做什么。最简单的方法是让
应用程序
由两种类型的应用程序组成,只要您不使用它们:

impl<T, U> fmt::Display for App<i32, App<T, U>> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Semi-awesome")
    }
}
请与我们联系

fn main() {
    let a = App(42i32, false);
    println!("{}", a);
    let b = App(100, a);
    println!("{}", b);
    let c = App(100, b);
    println!("{}", c);
}

我有一个猜测,接下来的问题将是关于所有非特殊条件的某种回退或默认情况。比如:

impl fmt::Display for App<i32, bool> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Awesome choice!")
    }
}

impl<T: fmt::Display, U: fmt::Display> fmt::Display for App<T, U> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Boring: {} + {}", self.0, self.1)
    }
}
impl fmt::应用程序的显示{
fn fmt(&self,f:&mut fmt::Formatter)->fmt::Result{
写!(f,“很棒的选择!”)
}
}
impl fmt::应用程序的显示{
fn fmt(&self,f:&mut fmt::Formatter)->fmt::Result{
写!(f,“无聊:{}+{}”,self.0,self.1)
}
}
不,那不会编译的
i32和
bool
也实现了
Display
,因此选择哪个实现是不明确的。在这一点上,你是进入的领域。这迫使您真正理解孤儿规则


据我所知,专业化的当前实现方式,你不能专门化具体类型,只能专注于特征。

有趣的是,我不需要
App
在这里-这是因为你说
Term
只有在
App
的两个孩子都是同一类型时才能实现<代码>应用程序
是可以的,
应用程序
不会。这意味着我确实需要它-我可能还没有触发错误,但我希望
应用程序
的不同变体也是
术语
s。我想知道几个单独的实现,但它仍然会带来麻烦,例如
应用程序
,因为内部的
App
再次需要2个类型参数-有什么办法吗?
impl<T, U> fmt::Display for App<i32, App<T, U>> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Semi-awesome")
    }
}
impl<T, U> fmt::Display for App<i32, App<T, U>>
    where App<T, U>: fmt::Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({}) squared!", self.1)
    }
}
fn main() {
    let a = App(42i32, false);
    println!("{}", a);
    let b = App(100, a);
    println!("{}", b);
    let c = App(100, b);
    println!("{}", c);
}
impl fmt::Display for App<i32, bool> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Awesome choice!")
    }
}

impl<T: fmt::Display, U: fmt::Display> fmt::Display for App<T, U> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Boring: {} + {}", self.0, self.1)
    }
}