为什么在 trait 方法声明中允许使用 unsized 类型?例如,此代码编译:
trait Blah {
fn blah(&self, input: [u8]) -> dyn Display;
}
Run Code Online (Sandbox Code Playgroud)
但实施Blah是不可能的:
impl Blah for Foo {
fn blah(&self, input: [u8]) -> dyn Display {
"".to_string()
}
}
// error[E0277]: the size for values of type `(dyn std::fmt::Display + 'static)` cannot be known at compilation time
// error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
Run Code Online (Sandbox Code Playgroud)
给出blah默认实现也是不可能的:
trait Blah {
fn blah(&self, input: dyn Display) -> dyn Display { "".to_string() }
}
// error[E0277]: the size for values of type `(dyn std::fmt::Display + 'static)` cannot be known at compilation time
Run Code Online (Sandbox Code Playgroud)
也不允许嵌套的 unsized 类型。这种不一致让我认为这是一个编译器错误:
trait Blah {
fn blah(&self, input: [str]) -> dyn Display;
}
// error[E0277]: the size for values of type `str` cannot be known at compilation time
Run Code Online (Sandbox Code Playgroud)
我发现了几个旧的 GitHub 问题,声称这种行为是故意的,但我找不到原因。为什么这是故意行为?如果实现这种性质的特征是不可能的,为什么编译器不在特征声明中捕获它?
我相信这里有两个不同的问题:未调整大小的函数参数和未调整大小的返回类型。
\n未调整大小的函数参数实际上在 nightly Rust 中实现并可用feature(unsized_fn_params)。这很可能会在某个时候稳定下来,然后就有可能实现这样的特征:
trait Crab {\n fn pinch(&self, data: str);\n}\nRun Code Online (Sandbox Code Playgroud)\n目前在稳定的 Rust 中无法实现。
\n事实上,标准库使用此功能来实现FnOnce()forBox<dyn FnOnce()>,这需要移入方法*self中call_once。由于FnOnce(某种)外部可见\xc2\xb9,并且std始终允许使用不稳定的功能,因此可能没有任何方法可以在unsized_fn_params不允许特征函数拥有它们(稳定)的情况下实现(夜间)。然而,这只是猜测。
顾名思义,unsized_fn_params只影响参数;unsized_locals即使在(更广泛、更宽松、不太完整的功能)下,仍然不允许未调整大小的返回值。因此,允许的论点-> dyn Display远没有那么令人信服,并且有充分的理由表明这是一个实际的错误,或者至少值得一提。
我相信其中的“故意”部分实际上仅适用于参数类型,并且包含返回类型是一个意外。
\n\xc2\xb9 这些Fn特征很特殊,因为在稳定中它们只能与Fn(...)语法一起使用,而不是与 一起Fn<Args>使用,但在约束和特征对象中仍然有效。
| 归档时间: |
|
| 查看次数: |
80 次 |
| 最近记录: |