add example for wrapping generic classes
This commit is contained in:
parent
57735540e8
commit
64a6a02bf0
|
@ -82,6 +82,36 @@ When you need to share ownership of data between Python and Rust, instead of usi
|
|||
|
||||
A Rust `struct Foo<T>` with a generic parameter `T` generates new compiled implementations each time it is used with a different concrete type for `T`. These new implementations are generated by the compiler at each usage site. This is incompatible with wrapping `Foo` in Python, where there needs to be a single compiled implementation of `Foo` which is integrated with the Python interpreter.
|
||||
|
||||
Currently, the best alternative is to write a macro which expands to a new #[pyclass] for each instantiation you want:
|
||||
|
||||
```rust
|
||||
# #![allow(dead_code)]
|
||||
use pyo3::prelude::*;
|
||||
|
||||
struct GenericClass<T> {
|
||||
data: T
|
||||
}
|
||||
|
||||
macro_rules! create_interface {
|
||||
($name: ident, $type: ident) => {
|
||||
#[pyclass]
|
||||
pub struct $name {
|
||||
inner: GenericClass<$type>,
|
||||
}
|
||||
#[pymethods]
|
||||
impl $name {
|
||||
#[new]
|
||||
pub fn new(data: $type) -> Self {
|
||||
Self { inner: GenericClass { data: data } }
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
create_interface!(IntClass, i64);
|
||||
create_interface!(FloatClass, String);
|
||||
```
|
||||
|
||||
#### Must be Send
|
||||
|
||||
Because Python objects are freely shared between threads by the Python interpreter, there is no guarantee which thread will eventually drop the object. Therefore all types annotated with `#[pyclass]` must implement `Send` (unless annotated with [`#[pyclass(unsendable)]`](#customizing-the-class)).
|
||||
|
|
Loading…
Reference in New Issue