不能使用霓虹灯 JsArray:此函数采用 3 个参数,但提供了 2 个

Can't use a neon JsArray: This function takes 3 parameters but 2 were supplied

我正在学习如何使用霓虹灯,但我什么都不懂。如果我尝试执行此代码:

#[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)
});

调用 js_arr.set 时出现此错误:This function takes 3 parameters but 2 were supplied.

我不明白为什么,因为它是 JsArray。甚至 Racer 告诉我 set 方法有 2 个参数。无论如何,js_arr.set 按顺序接受 3 个参数:&mut boolneon::macro_internal::runtime::raw::Localneon::macro_internal::runtime::raw::Local.

发生了什么事?我无法理解 JsArray 是如何工作的。

let js_arr: Handle<JsArray>明确表示js_arr是一个Handle<JsArray>Handle<T>有这个方法:

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

我猜你是不小心尝试调用 Handle::set (which is unsafe and takes three non-self arguments) rather than JsArray::set(这是安全的,需要两个非 self 参数)。

如果是这种情况,您需要强制执行 deref_mut。 (_mut 因为 JsArray::set 需要 &mut self。)

我以前没有 运行 遇到过这种命名冲突,所以我不能确定 auto-deref 是否足够聪明,但这样的事情可能会起作用:

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

如果做不到这一点,可以尝试另外两件事:

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

    (如果前一个示例失败,因为它太像 C++ 风格的方法重载。这称为 Fully Qualified Syntax,通常用于消除对象实现两个提供同名方法的特征时的歧义.)

  2. 直接调用 js_arr.deref_mut() 以获得对底层 JsArray 的可变引用,然后在其上调用 set

作为 paulsevere says on a GitHub issue for Neon,导入 neon::js::Object。另外,做not import Key,也提供了一个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)
});

这将创建一个全新的数组。如果你想接受一个数组作为函数的第一个参数然后修改它,这是可行的:

#[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)
});