I am using functions from std::fs
, which take arguments such as path: impl AsRef<Path>
. I wish to make my own functions polymorphic so they too can take any impl AsRef<Path>
rather than accepting only &str
. However, the path-like object in question must be stored inside one of my structs. This means it must be stored as Box<dyn AsRef<Path>>
to give it a known size. I am struggling to convert this boxed value into anything that can be accepted by the std::fs
functions.
Consider the following code:
use std::path::Path;
fn main() {
fn polymorphic(_: impl AsRef<Path>) {}
let boxed: Box<dyn AsRef<Path>> = Box::new("/foo/bar");
polymorphic(/*???*/);
}
What do I replace the question marks with to allow me to call polymorphic
with "/foo/bar"
?
Dereference and re-reference the Box
:
use std::path::Path;
fn main() {
fn polymorphic(_: impl AsRef<Path>) {}
let boxed: Box<dyn AsRef<Path>> = Box::new("/foo/bar");
polymorphic(&*boxed);
}
This means it must be stored as
Box<dyn AsRef<Path>>
No it doesn't. The documentation of Path
states (emphasis mine):
This is an unsized type, meaning that it must always be used behind a pointer like
&
orBox
. For an owned version of this type, seePathBuf
.
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)
}
}
I would actually use Into<PathBuf>
myself, as this allows someone to give me ownership of something they no longer need:
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)
}
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments