Wasm-bindgen: Usage of dyn_ref vs dyn_into

Created on 4 Aug 2019  路  2Comments  路  Source: rustwasm/wasm-bindgen

Summary

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?

Additional Details

I finished reading the Rust Programming Language Book, but am new to wasm-bindgen, web-sys, and js-sys.

question

Most helpful comment

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 self
  • dyn_into returns a T, and it consumes self so you can no longer use it

Which 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.

All 2 comments

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 self
  • dyn_into returns a T, and it consumes self so you can no longer use it

Which 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!

Was this page helpful?
0 / 5 - 0 ratings