2017-08-05 5 views
1

J'apprends à utiliser le néon, mais je ne comprends rien. Si je tente d'exécuter ce code:Impossible d'utiliser un néon JsArray: Cette fonction prend 3 paramètres mais 2 ont été fournis

#[macro_use] 
extern crate neon; 
use neon::vm::{Call, JsResult}; 
use neon::mem::Handle; 
use neon::js::{JsInteger, JsNumber, JsString, JsObject, JsArray, JsValue, Object, Key}; 
use neon::js::error::{JsError, Kind}; 

fn test(call: Call) -> JsResult<JsArray> { 
    let scope = call.scope; 
    let js_arr: Handle<JsArray> = try!(try!(call.arguments.require(scope, 1)).check::<JsArray>()); 

    js_arr.set(0, JsNumber::new(scope, 1000)); 

    Ok(js_arr) 
} 

register_module!(m, { 
    m.export("test", test) 
}); 

Je reçois cette erreur quand je l'appelle js_arr.set: This function takes 3 parameters but 2 were supplied.

Je ne comprends pas pourquoi car il est un JsArray. Même Racer me dit que la méthode set prend 2 paramètres. Peu importe quoi, js_arr.set prend 3 paramètres dans cet ordre: &mut bool, neon::macro_internal::runtime::raw::Local et neon::macro_internal::runtime::raw::Local.

Que se passe-t-il? Je ne peux pas comprendre comment fonctionne JsArray.

+0

Je vois que vous [ouvriez un problème dans le dépôt au néon] (https: // GitHub. com/neon-bindings/neon/issues/218) - avez-vous également lu le [numéro existant sur 'JsArray'] (https://github.com/neon-bindings/neon/issues/57)? – Shepmaster

+0

@Shepmaster Trouvé le chemin, désolé si j'ai été impoli, merci d'aider. – pietrovismara

+0

Pas de soucis; Je comprends parfaitement comment essayer de trouver un nouveau langage ou une nouvelle bibliothèque peut être frustrant! Les bonnes nouvelles sont qu'il semble que beaucoup d'autres personnes ont eu le même problème sous-jacent. – Shepmaster

Répondre

1

En tant que paulsevere says on a GitHub issue for Neon, importez neon::js::Object. En outre, ne pas importation Key, qui fournit également une méthode set:

#[macro_use] 
extern crate neon; 

use neon::vm::{Call, JsResult}; 
use neon::js::{Object, JsArray, JsInteger, JsObject, JsNumber}; 

fn make_an_array(call: Call) -> JsResult<JsArray> { 
    let scope = call.scope; // the current scope for rooting handles 
    let array = JsArray::new(scope, 3); 
    array.set(0, JsInteger::new(scope, 9000))?; 
    array.set(1, JsObject::new(scope))?; 
    array.set(2, JsNumber::new(scope, 3.14159))?; 
    Ok(array) 
} 

register_module!(m, { 
    m.export("main", make_an_array) 
}); 

Cela crée une toute nouvelle gamme. Si vous souhaitez accepter un tableau comme premier argument à votre fonction, puis le modifier, cela fonctionne:

#[macro_use] 
extern crate neon; 

use neon::vm::{Call, JsResult}; 
use neon::js::{Object, JsArray, JsInteger, JsUndefined}; 
use neon::mem::Handle; 

fn hello(call: Call) -> JsResult<JsUndefined> { 
    let scope = call.scope; 
    let js_arr: Handle<JsArray> = call.arguments.require(scope, 0)?.check::<JsArray>()?; 

    js_arr.set(0, JsInteger::new(scope, 1000))?; 

    Ok(JsUndefined::new()) 
} 

register_module!(m, { 
    m.export("hello", hello) 
}); 
+0

@pietrovismara * J'ai déjà importé 'JsObject' * - pas le ** type **' JsObject', le ** trait ** 'Object'. Il y a une différence, ce qui expliquerait pourquoi cela n'a pas fonctionné. – Shepmaster

+0

C'est vrai (faute de frappe), mais si vous regardez ma question, vous pouvez voir que j'ai aussi importé 'Object'. Je suppose que peut-être l'ordre de l'importation ou quelque chose d'autre a fait la différence? – pietrovismara

+1

@pietrovismara ah, compris; Il s'agit de 'Key' - qui ajoute une autre méthode appelée' set' qui provoque le problème. – Shepmaster

1

let js_arr: Handle<JsArray> montre clairement que js_arr est un Handle<JsArray> et Handle<T> a cette méthode:

unsafe fn set(self, out: &mut bool, obj: Local, val: Local) -> bool 

Je suppose que vous essayez d'appeler accidentellement Handle::set (qui est unsafe et prend trois arguments non self) plutôt que JsArray::set (qui est sûr et prend deux arguments non self).

Si c'est le cas, vous devez forcer deref_mut à se produire. (_mut parce JsArray::set prend &mut self.)

Je n'ai pas courir dans ce genre de collision nommant avant, donc je ne peux pas être certain que le auto-deref est assez intelligent, mais quelque chose comme cela peut fonctionner:

(&mut js_arr).set(0, JsNumber::new(scope, 1000)); 

A défaut, deux autres choses à essayer sont:

  1. JsArray::set(&mut js_arr, 0, JsNumber::new(scope, 1000));

    (Si l'exemple précédent échoue parce que cela ressemble trop à une surcharge de méthode de style C++. Ceci est connu comme Fully Qualified Syntax et est normalement utilisé pour désambiguïser lorsqu'un objet implémente deux traits qui fournissent des méthodes du même nom.)

  2. Appelez js_arr.deref_mut() directement pour obtenir une référence mutable à la JsArray sous-jacente, puis appelez set sur ce point.

+0

* quelque chose comme ça peut fonctionner * - pourquoi ne pas l'essayer au lieu de deviner? – Shepmaster

+2

@Shepmaster Neon ne fait pas partie du Rust Playground et je n'ai pas le temps de me tromper en installant un environnement de test sur ma propre machine en ce moment. (Je n'ai jamais utilisé Node.js au-delà de 'npm install -g. S'il s'agissait d'une question' rust-cpython', je pourrais simplement insérer une ligne dans un de mes projets existants pour un test rapide.) – ssokolow

+1

Je dois définir quelque chose. Il est lié dynamiquement, de sorte que vous pouvez obtenir le code Rust à compiler, puis il échouera à lier plus tard. – Shepmaster