我正在使用std::fs
中的函数,这些函数带有诸如path: impl AsRef<Path>
之类的参数。我希望使自己的函数具有多态性,以便它们也可以采用任何impl AsRef<Path>
而不是仅接受&str
。但是,所讨论的类似路径的对象必须存储在我的一个结构中。这意味着必须将其存储为Box<dyn AsRef<Path>>
才能获得已知大小。我正在努力将这个装箱的值转换为std::fs
函数可以接受的任何值。
考虑以下代码:
use std::path::Path;
fn main() {
fn polymorphic(_: impl AsRef<Path>) {}
let boxed: Box<dyn AsRef<Path>> = Box::new("/foo/bar");
polymorphic(/*???*/);
}
如何用问号代替问号,以便我可以用polymorphic
来呼叫"/foo/bar"
?
答案 0 :(得分:4)
取消引用并重新引用Box
:
use std::path::Path;
fn main() {
fn polymorphic(_: impl AsRef<Path>) {}
let boxed: Box<dyn AsRef<Path>> = Box::new("/foo/bar");
polymorphic(&*boxed);
}
这意味着它必须存储为
Box<dyn AsRef<Path>>
不,不是。 Path
状态的文档(强调我的观点):
这是一个无大小的类型,意味着必须始终在诸如
&
或Box
之类的指针后面使用它。 有关此类型的拥有版本,请参见PathBuf
。
use std::path::{Path, PathBuf};
fn polymorphic(_: impl AsRef<Path>) {}
struct Example(PathBuf);
impl Example {
fn new(path: impl AsRef<Path>) -> Self {
Self(path.as_ref().to_owned())
}
fn example(&self) {
polymorphic(&self.0)
}
}
我实际上会自己使用Into<PathBuf>
,因为这可以使某人将不再需要的东西授予我所有权:
use std::path::{Path, PathBuf};
fn polymorphic(_: impl AsRef<Path>) {}
struct Example(PathBuf);
impl Example {
fn new(path: impl Into<PathBuf>) -> Self {
Self(path.into())
}
fn example(&self) {
polymorphic(&self.0)
}
}