在编译时没有已知的大小

Anu*_*aki 3 rust

use std::fmt::Debug;

#[derive(Debug)]
struct Node<K: Debug, V: Debug> {
    key: K,
    value: V,
}

fn myprint<K: Debug + ?Sized, V: Debug + ?Sized>(node: &Node<K,V>) -> String {
    return format!("{:?}: {:?}", node.key, node.value);
}

fn main() {
    let node = Node{key: "xxx", value: "yyy"};
    myprint(&node);
}
Run Code Online (Sandbox Code Playgroud)

编译错误:

use std::fmt::Debug;

#[derive(Debug)]
struct Node<K: Debug, V: Debug> {
    key: K,
    value: V,
}

fn myprint<K: Debug + ?Sized, V: Debug + ?Sized>(node: &Node<K,V>) -> String {
    return format!("{:?}: {:?}", node.key, node.value);
}

fn main() {
    let node = Node{key: "xxx", value: "yyy"};
    myprint(&node);
}
Run Code Online (Sandbox Code Playgroud)

但以下代码有效:

use std::fmt::Debug;

fn debug<T: Debug + ?Sized>(t: &T) { // T: Debug + ?Sized
    println!("{:?}", t);
}

fn main() {
    debug("my str"); // T = str, str: Debug + ?Sized ??
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*erg 7

所有类型参数都是隐式的Sized

这意味着struct Node<K: Debug, V: Debug> {...}struct Node<K: Debug + Sized, V: Debug + Sized> {...}.

为了允许Sized删除绑定,?Sized添加了特殊语法。这意味着类型参数是可选的 not Sized

在功能上myprint<K:Debug + ?Sized, V:Debug + ?Sized>,您允许 K不是 Sized。同时,KinNode<K,V>必须是Sized。这意味着存在myprint允许但不能编译的类型参数。

完全相同的问题也适用于V.


如何解决这个问题

那么,第一个问题是你需要支持?Sizedas aK还是Vin a Node?如果没有,您的函数也不需要支持它。

fn myprint<K: Debug, V: Debug>(node: &Node<K,V>) {...}
Run Code Online (Sandbox Code Playgroud)

另一方面,如果您打算支持?Sized K/ V,则需要正确定义结构:

struct Node<K: Debug + ?Sized, V: Debug + ?Sized> {...}
Run Code Online (Sandbox Code Playgroud)

但是 fn debug<T: Debug+?Sized>(t: &T) 可以工作!

是的。这是一个有效的签名。它在另一个函数中不起作用的原因是另一个函数说KDebug + ?Sized需要使用定义为的类型,Node<K, V>其中是Debug + Sized(无问号)上下文。