
[ad_1]
Explorer cette interface conviviale

En raison du modèle de mémoire de WASM, le passage de tableaux (et de tableaux imbriqués) peut être assez difficile si vous essayez de faire les choses en toute sécurité, car la mémoire wasm stocke ses valeurs sous forme de tampons de tableau de types scalaires.
Cependant, nous avons heureusement le wasm-bindgen
(et js-sys
) crates qui fournissent une interface conviviale sur laquelle travailler lors de l’échange de données entre Javascript et WebAssembly.
Je dois également mentionner que chaque fois que vous travaillez avec WebAssembly, vous devez toujours éviter d’échanger des données entre JS et votre binaire WASM si vous développez avec la performance comme l’un de vos objectifs.
En règle générale, nous souhaitons que WASM fonctionne avec des calculs, des requêtes et des données lourds dans sa mémoire linéaire et ne renvoie que de petites quantités de données en raison des calculs.
Les fonctions Wasm prennent et renvoient des valeurs scalaires sous forme de ArrayBuffer
. Heureusement wasm-bindgen
aide avec beaucoup de choses, mais il ne fait pas tout.
Voyons comment vous pouvez passer (ou retourner) des tableaux en utilisant le type.
Puisque nous travaillons avec WebAssembly, plus précisément, qui cible une construction Web (elle est censée fonctionner avec js), la meilleure configuration que nous pouvons obtenir consiste à utiliser wasm-bindgen
avec ses macros procédurales.
Vous pouvez consulter cet article pour une introduction plus détaillée et plus complète à la configuration et à WASM+Rust en général, mais voici un petit récapitulatif :
Ajout des dépendances nécessaires
Ajoutez ces deux dépendances dans votre Cargo.toml
configs (assurez-vous d’utiliser les versions les plus récentes) :
wasm-bindgen = "0.2.82"
js-sys = "0.3.59"
Optimisations WASM
Vous devez également ajouter les éléments suivants à vos configurations :
[profile.release]
opt-level = "z"
overflow-checks = true
debug = 0
strip = "symbols"
debug-assertions = false
panic = "abort"
codegen-units = 1
lto = true[profile.dev]
opt-level = 0
panic = 'abort'
Ceux-ci ajouteront des paramètres lors de la compilation de votre code, ce qui est également bénéfique en termes de taille de code (par exemple, abandonner en cas de panique pour réduire la taille du code).
Enfin, vous devrez indiquer au compilateur que la compilation produira une bibliothèque système dynamique ("cdylib"
) et des exécutables liés statistiquement ("rlib"
le contenu est inséré dans l’exécutable).
[lib]
crate-type = ["cdylib", "rlib"]
Comme je l’ai laissé entendre en important le js_sys
dépendance, nous allons utiliser la js_sys::Array
taper.
Disons que nous avons une fonction Rust my_funct
qui prend un tableau en paramètre. Voici à quoi cela ressemblerait en utilisant le js_sys::Array
taper:
#[wasm_bindgen]
pub fn my_funct(
my_arr: Array,
)
C’est une construction très simple qui ne demande presque aucun effort de notre part. Cependant, l’effort réside dans la façon de traiter ce Array
taper. Par exemple, vous ne pouvez pas avoir de tableau imbriqué et le type de valeur est inconnu (puisque JS n’a pas de typage fort).
Tableaux imbriqués
Comme je l’ai mentionné, le Array
type ne prend pas en charge les tableaux imbriqués. C’est parce que vous ne pouvez pas lancer un élément de Array
à un vecteur.
Vous avez quelques options ici. Tu pourrais passer [["hey"], ["tdep"]]
puis analysez les éléments du tableau en une chaîne avec :
my_arr.get(index).as_string().unwrap()
Et puis désérialiser la chaîne avec une bibliothèque comme serde_json
.
Une autre option, que je préfère car elle me permet de travailler avec des tableaux imbriqués sans utiliser de dépendance supplémentaire, consiste à passer des tableaux multidimensionnels en tant que tableau unidimensionnel, puis à les intégrer dans un tableau imbriqué sur Rust.
C’est assez facile si vous connaissez la longueur du tableau. Disons que vous savez que vous devez prendre un tableau de quatre éléments, puis en construire un imbriqué avec deux tableaux ressemblant à ceci [["el1", "el2"], ["el3", "el4"]]
. Si tel est le cas, vous pouvez facilement résoudre le problème avec :
[
[
&arr.get(0).as_string().unwrap(),
&arr.get(1).as_string().unwrap(),
],
[
&arr.get(2).as_string().unwrap(),
&arr.get(3).as_string().unwrap(),
]
]
Cependant, vous pouvez travailler avec des vecteurs et faire passer à JS un tableau de longueur inconnue au moment de la compilation, et vous devez toujours créer un tableau imbriqué où chaque élément est un tableau contenant deux éléments.
J’ai décidé d’implémenter cet algorithme manuellement car il est assez simple à écrire :
Les boucles de code ci-dessus de notre my_arr
tableau, et pousse un nouveau tableau de deux éléments dans le my_arr_vec
vecteur tous les deux pas.
Cela signifie que notre boucle fonctionnera tant que nous recevrons un tableau avec un nombre pair comme longueur (puisque nous voulons construire un vecteur avec des tableaux de deux éléments à l’intérieur).
[ad_2]
Télécharger ici