我定义了一个特征ReadTag,其中包含一个返回的函数Self,但这样会产生错误:
trait ReadTag {
fn read_out(buf: &mut &[u8]) -> Option<Self>;
}
Run Code Online (Sandbox Code Playgroud)
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> src/lib.rs:2:37
|
2 | fn read_out(buf: &mut &[u8]) -> Option<Self>;
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
Run Code Online (Sandbox Code Playgroud)
Sized通过添加为超级特征来修复错误,这是有道理的,但为什么Sized不像函数那样默认呢?
fn my_sized<T>(t: T) { } // all good, Sized is opt-out :)
fn my_unsized<T: ?Sized>(t: T) { } // not allowed
Run Code Online (Sandbox Code Playgroud) 由于违反借用检查规则,不允许使用以下程序:
struct Foo;
impl Foo {
fn bar(&mut self, i: u8) { }
fn baz(&mut self) -> u8 { 0 }
}
fn main() {
let mut foo = Foo;
foo.bar(foo.baz())
// --------^^^^^^^^^-
// | | |
// | | second mutable borrow occurs here
// | first borrow later used by call
// first mutable borrow occurs here
}
Run Code Online (Sandbox Code Playgroud)
但是您可以通过绑定到临时变量来解决此问题,例如:
fn main() {
let mut foo = Foo;
let t = foo.baz();
foo.bar(t);
}
Run Code Online (Sandbox Code Playgroud)
为什么借用检查器从最外层函数调用开始?难道不应该反过来吗?
我正在创建一个接口,它在通用特征实现器上构建一个运行器:
use std::sync::mpsc::Sender;
trait Poll {
type Output;
type Config: 'static;
fn poll(cfg: Self::Config, tx: Sender<Self::Output>) -> !;
}
struct Runner<P: Poll>(P, Option<P::Config>);
impl<P: Poll> Runner<P> {
fn run(poller: P) -> Self {
Self(poller, None)
}
fn with_config(mut self, cfg: P::Config) -> Self {
self.1 = Some(cfg);
self
}
fn on(mut self, tx: Sender<P::Output>) -> ! {
let config: P::Config = {
todo!()
};
P::poll(config, tx);
}
}
Run Code Online (Sandbox Code Playgroud)
on如果用户不向构建器提供配置,我希望以某种方式失败。我也想with_config成为可选的如果P::Config == ()。
我想我可以通过确定配置的类型来做到这一点std::any::TypeId,但我不确定之后将单位转换为这样的通用单位是否安全。
use …Run Code Online (Sandbox Code Playgroud)