When would you use dyn_ref vs dyn_into? From the book examples, it is hard for me to see the difference between them. My guess is that dyn_ref is used for converting a JsValue that is already owned by some other variable while dyn_into is for converting a JsValue that is not owned by another variable.
Also, why does dyn_ref return a Option while dyn_into returns an Result?
I finished reading the Rust Programming Language Book, but am new to wasm-bindgen, web-sys, and js-sys.
If you have a &self then you have to use dyn_ref.
If you have a self then you can choose whether to use dyn_ref or dyn_into:
dyn_ref returns a &T, and you can continue to use selfdyn_into returns a T, and it consumes self so you can no longer use itWhich one should you use? It depends on whether you have a self or &self, and it depends on whether you need a T, or whether a &T is good enough. That's all there is to it.
Because Rust's ownership model is pervasive throughout the language, this sort of owned/ref/mut split is quite common.
For example, with iterators you have into_iter for the owned version, iter for the & version, and iter_mut for the &mut version.
The reason why dyn_into returns a Result is because the conversion might fail.
Also, because dyn_into accepts self by value, that means you cannot use self after calling dyn_into.
But if dyn_into fails, you probably still want access to self, and so dyn_into returns Err(self). This lets you do something like this:
match foo.dyn_into() {
Ok(t) => {
// Successfully converted into T, and foo is consumed
},
Err(foo) => {
// foo is the original value
},
}
That means that dyn_into only consumes self if conversion succeeds. But if conversion fails then it will return self back to the caller.
So why doesn't dyn_ref return a Result? It accepts &self, which means it doesn't consume self, so you can continue to use self even after you call dyn_ref. Thus there's no need to return Err(self), so it returns None instead.
@Pauan Thanks for the crystal clear answer!
Most helpful comment
If you have a
&selfthen you have to usedyn_ref.If you have a
selfthen you can choose whether to usedyn_refordyn_into:dyn_refreturns a&T, and you can continue to useselfdyn_intoreturns aT, and it consumesselfso you can no longer use itWhich one should you use? It depends on whether you have a
selfor&self, and it depends on whether you need aT, or whether a&Tis good enough. That's all there is to it.Because Rust's ownership model is pervasive throughout the language, this sort of owned/
ref/mutsplit is quite common.For example, with iterators you have
into_iterfor the owned version,iterfor the&version, anditer_mutfor the&mutversion.The reason why
dyn_intoreturns aResultis because the conversion might fail.Also, because
dyn_intoacceptsselfby value, that means you cannot useselfafter callingdyn_into.But if
dyn_intofails, you probably still want access toself, and sodyn_intoreturnsErr(self). This lets you do something like this:That means that
dyn_intoonly consumesselfif conversion succeeds. But if conversion fails then it will returnselfback to the caller.So why doesn't
dyn_refreturn aResult? It accepts&self, which means it doesn't consumeself, so you can continue to useselfeven after you calldyn_ref. Thus there's no need to returnErr(self), so it returnsNoneinstead.