簡體   English   中英

不滿足特征綁定`T:std :: fmt :: Display`

[英]The trait bound `T: std::fmt::Display` is not satisfied

我正在寫一個基本的二叉樹結構,我想顯示一個節點。 似乎Rust無法顯示通用類型,但出現此錯誤:

error[E0277]: the trait bound `T: std::fmt::Display` is not satisfied
  --> src/main.rs:55:60
   |
55 |         write!(f, "Node data: {} left: {:?}, right: {:?}", self.data, self.left, self.right);
   |                                                            ^^^^^^^^^ trait `T: std::fmt::Display` not satisfied
   |
   = help: consider adding a `where T: std::fmt::Display` bound
   = note: required by `std::fmt::Display::fmt`

error[E0277]: the trait bound `T: std::fmt::Display` is not satisfied
  --> src/main.rs:62:60
   |
62 |         write!(f, "Node data: {} left: {:?}, right: {:?}", self.data, self.left, self.right);
   |                                                            ^^^^^^^^^ trait `T: std::fmt::Display` not satisfied
   |
   = help: consider adding a `where T: std::fmt::Display` bound
   = note: required by `std::fmt::Display::fmt`

這是完整的代碼,包括迭代器

struct Node<T> {
    data: T,
    left: Option<Box<Node<T>>>,
    right: Option<Box<Node<T>>>,
}

struct NodeIterator<T> {
    nodes: Vec<Node<T>>,
}

struct Tree<T> {
    root: Option<Node<T>>,
}

impl<T> Node<T> {
    pub fn new(value: Option<T>,
               left: Option<Box<Node<T>>>,
               right: Option<Box<Node<T>>>)
               -> Node<T> {
        Node {
            data: value.unwrap(),
            left: left,
            right: right,
        }
    }

    pub fn insert(&mut self, value: T) {
        println!("Node insert");
        match self.left {
            Some(ref mut l) => {
                match self.right {
                    Some(ref mut r) => {
                        r.insert(value);
                    } 
                    None => {
                        self.right = Some(Box::new(Node::new(Some(value), None, None)));
                    }
                }
            }
            None => {
                self.left = Some(Box::new(Node::new(Some(value), None, None)));
            }
        }
    }
}

impl<T> std::fmt::Display for Node<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f,
               "Node data: {} left: {:?}, right: {:?}",
               self.data,
               self.left,
               self.right);
    }
}

impl<T> std::fmt::Debug for Node<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f,
               "Node data: {} left: {:?}, right: {:?}",
               self.data,
               self.left,
               self.right);
    }
}

impl<T> Iterator for NodeIterator<T> {
    type Item = Node<T>;
    fn next(&mut self) -> Option<Node<T>> {
        if self.nodes.len() == 0 {
            None
        } else {
            let current: Option<Node<T>> = self.nodes.pop();
            for it in current.iter() {
                for n in it.left.iter() {
                    self.nodes.push(**n);
                }
                for n in it.right.iter() {
                    self.nodes.push(**n);
                }
            }
            return current;
        }
    }
}

impl<T> Tree<T> {
    pub fn new() -> Tree<T> {
        Tree { root: None }
    }

    pub fn insert(&mut self, value: T) {
        match self.root {
            Some(ref mut n) => {
                println!("Root is not empty, insert in node");
                n.insert(value);
            }
            None => {
                println!("Root is empty");
                self.root = Some(Node::new(Some(value), None, None));
            }
        }
    }

    fn iter(&self) -> NodeIterator<T> {
        NodeIterator { nodes: vec![self.root.unwrap()] }
    }
}

fn main() {
    println!("Hello, world!");

    let mut tree: Tree<i32> = Tree::new();
    tree.insert(42);
    tree.insert(43);

    for it in tree.iter() {
        println!("{}", it);
    }
}

這是此問題的最低版本:

struct Bob<T>(T);

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

fn main() {
    let x = Bob(4);
    println!("{}", x);
}

讓我們看一下我們的fmt函數:

fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
    write!(f, "Bob: {}", self.0)
}

為了更清楚,我們可以按如下方式重寫它:

fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
    write!(f, "Bob: ")?;
    std::fmt::Display::fmt(&self.0, f)
}

用雙引號"{}"括起來的格式宏( write!format!println!等)中的一個調用,表示從Display trait調用該參數的fmt函數(在本例中為self.0 。 )。

問題是我們有一些通用類型T ,因此編譯器不知道是否為此實現了Display

有兩種方法可以解決此問題。

首先,我們可以將約束T: std::fmt::Display到我們的BobDisplay實現中。 這將使我們將結構與非Display類型一起使用,但是Display僅在與Display類型一起使用時才會實現。

該修復程序如下所示:

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

其次,我們可以將該約束添加到結構定義中,如下所示:

struct Bob<T: std::fmt::Display>(T);

這將意味着Bob僅在Display類型方面是通用的。 它更具局限性,並限制了Bob的靈活性,但在某些情況下可能需要這樣做。


可以通過將不同的標記放在方括號中來調用類似於Display其他特征。 完整列表可以在文檔中找到,但是,例如,我們可以將Debug trait與

write!(f, "Bob: {:?}", self.0)

只有這樣,我們才需要確保Tstd::fmt::Debug

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM