有这么一个函数:
pub fn new<B>() -> Result<Terminal<B>> {
let backend = CrosstermBackend::new(io::stdout());
Terminal::new(backend)
}
其中CrosstermBackend的大致定义:
pub struct CrosstermBackend<W: Write>;
impl<W> Backend for CrosstermBackend<W>
where W: Write {}
Terminal的定义:
pub struct Terminal<B>
where B: Backend {}
报错如下:
error[E0308]: mismatched types
--> src/term.rs:13:19
|
11 | pub fn new<B: Backend>() -> Result<Terminal<B>> {
| - this type parameter
12 | let backend = CrosstermBackend::new(io::stdout());
13 | Terminal::new(backend)
| ------------- ^^^^^^^ expected type parameter `B`, found struct `CrosstermBackend`
| |
| arguments to this function are incorrect
|
= note: expected type parameter `B`
found struct `CrosstermBackend<Stdout>`
note: associated function defined here
--> /home/jedsek/.cargo/registry/src/mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd/tui-0.19.0/src/terminal.rs:175:12
|
175 | pub fn new(backend: B) -> io::Result<Terminal<B>> {
| ^^^
For more information about this error, try `rustc --explain E0308`.
error: could not compile `ncm-tui` due to previous error
但是换成impl后就可以了:
pub fn new() -> Result<Terminal<impl Backend>> {
let backend = CrosstermBackend::new(io::stdout());
Terminal::new(backend)
}
这是为什么?
1
共 3 条评论, 1 页
评论区
写评论rust论坛上有个答案:
strange for me
回答:
Self is the type being implemented, so it's Struct. The method Struct::new() takes a value of type T, which is a generic parameter, so whoever uses the type can choose it. So it doesn't make sense to call it with a value of type StructB – what if someone calls Struct::::a(), what should happen, then?
可为什么我把调用放在main函数就没有问题?
--
👇
7sDream: 因为你这个函数返回的确切类型只有一个,调用方无法通过 B 这个泛型参数来要求这个函数返回某个其他类型。
impl Trait
这个语法在参数位置的含义和在返回值位置里的含义不一样。在参数里的含义是你认为的这种泛型参数的简写;而在返回值里的含义其实是返回一个确定的,实现了某个 Trait 的匿名类型,而不是泛型。详细可参阅TRPL 相关章节和对应 RFC。
因为你这个函数返回的确切类型只有一个,调用方无法通过 B 这个泛型参数来要求这个函数返回某个其他类型。
impl Trait
这个语法在参数位置的含义和在返回值位置里的含义不一样。在参数里的含义是你认为的这种泛型参数的简写;而在返回值里的含义其实是返回一个确定的,实现了某个 Trait 的匿名类型,而不是泛型。详细可参阅TRPL 相关章节和对应 RFC。