I have the code:
#[derive(Clone)]
struct U;
fn main() {
let u = Some(U);
Option::cloned(u.as_mut());
}
Which fails with:
Option::cloned(u.as_mut());
^^^^^^^^^^ values differ in mutability
To clone I have to use .map(|t| t.clone())
directly.
Is there any way to use Option::cloned
when external method strictly returns Option<&mut T>
.
I feel .cloned()
has unflexble implementation. Am I right or wrong?
1 Like
This looks like an oversight to me. Perhaps you could open an issue on github, or even just write up a quick pull request and see what the standard lib team thinks.
Perhaps it should take any Deref
type?
impl<T: Clone, U: Deref<Target = T>> Option<U> {
fn cloned(self) -> Option<T> {
match self {
Some(u) => Some(u.clone()),
None => None,
}
}
}
playground
I think this wouldn't even be a breaking change. However, note that cloned(self)
is taken by value, which is normally painless since any Option<&T>
implements Copy
. That's harder to deal with for other Deref
types.
FWIW, I also tried AsRef<T>
, but then T
is not constrained in the impl. I think you could move the parameterization onto cloned
itself, but this will lean more heavily on type inference at the caller, which could break existing cloned
calls.
Thanks for useful ideas! I think I should to test an alternative implementation as change of standard library. Possible this improvement is worth to be a PR.