我正在编写一个基本的二叉树结构,我想显示一个节点.似乎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`
Run Code Online (Sandbox Code Playgroud)
这是完整的代码,包括迭代器
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);
}
}
Run Code Online (Sandbox Code Playgroud)
以下是此问题的最小版本:
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);
}
Run Code Online (Sandbox Code Playgroud)
我们来看看我们的fmt功能:
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Bob: {}", self.0)
}
Run Code Online (Sandbox Code Playgroud)
为了更清晰,我们可以按如下方式重写它:
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Bob: ")?;
std::fmt::Display::fmt(&self.0, f)
}
Run Code Online (Sandbox Code Playgroud)
调用格式化宏一(write!,format!,println!等)在引号双括号,"{}"说调用fmt从功能Display特征的这样的说法(self.0在这种情况下).
问题是我们有一些泛型类型T,因此编译器不知道是否Display实现了它.
有两种方法可以解决这个问题.
首先,我们可以将约束添加T: std::fmt::Display到Displayfor 的实现中Bob.这将允许我们使用非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)
}
}
Run Code Online (Sandbox Code Playgroud)
其次,我们可以将该约束添加到结构定义中,如下所示:
struct Bob<T: std::fmt::Display>(T);
Run Code Online (Sandbox Code Playgroud)
这意味着它Bob只是关于类型的通用Display.它更具限制性并限制了其灵活性Bob,但可能存在需要的情况.
Display通过在括号中放置不同的标记,可以调用其他类似的特征.完整列表可以在文档中找到,但是,例如,我们可以使用Debug特征
write!(f, "Bob: {:?}", self.0)
Run Code Online (Sandbox Code Playgroud)
只有这样我们才能确定那T是std::fmt::Debug.