Рай: Область видимости доступна только для напрямую вызываемой функции?

В моем скрипте rhai есть две функции, direct и indirect, и я хотел бы предоставить переменные с помощью Scope. (Т.е. я не хотел бы передавать их в качестве аргументов функциям.) Когда я вызываю direct с областью видимости, скрипт, по-видимому, может получить доступ к переменной из области.

Однако, когда я вызываю indirect (который делегаты работают с direct), выполнение завершается ошибкой, потому что не может найти переменные в Scope.

Эта программа демонстрирует мою проблему. (Обратите внимание на последний вызов expect_err, который показывает, что indirect не может получить доступ к x из scope.)

use rhai::{Engine, Scope}; 
 
#[allow(unused_must_use)] 
fn main() { 
    let engine = Engine::new(); 
    let ast = engine.compile(r" 
        fn direct() { 
            print(x); // <----- Note: This uses x, which is assumed to be supplied by Scope 
        } 
        fn indirect() { 
            direct(); 
        } 
    ").unwrap(); 
 
    // I understand this (x not in scope) 
    engine.call_fn::<()>(&mut Scope::new(), &ast, "direct", ()) 
        .expect_err("Because of missing 'x'"); 
 
    let mut scope = Scope::new(); 
    scope.push("x", 1); 
 
    engine.call_fn::<()>(&mut scope, &ast, "direct", ()) 
        .expect("Works as expected as 'x' is supplied by scope."); 
 
    engine.call_fn::<()>(&mut scope, &ast, "indirect", ()) 
        .expect_err("This returns Err although 'x' is supplied by scope - why?"); // <--- Can I make this call work?
}

Из здесь и здесь Я ожидал, что даже вызов indirect позволит вызываемому direct получить доступ к переменным из scope. Моя интерпретация здесь неверна?

Или, альтернативно: есть ли способ, который позволил бы мне успешно вызвать indirect, указав значение x в Scope?

Никогда не слышал о Rhai, но, судя по документации, это просто семантика языка. Область, которую вы передаете, назначается вызываемой вами функции, но она не передается вложенным вызовам, если вы не используете специальный синтаксис. Я не могу больше сказать вам, так как я никогда не использовал язык. :)

Sven Marnach 03.12.2022 17:02

@SvenMarnach Спасибо. Я не ожидал, что это будет "продвинутая тема". Если вы хотите добавить ответ, я с радостью приму его.

phimuemue 03.12.2022 20:38

Я действительно не знаю, о чем говорю, и не чувствую себя вправе отвечать. Я только что потратил 30 секунд на гугление и случайно наткнулся на эту страницу — я даже не заметил, что она находится в разделе «расширенные темы».

Sven Marnach 03.12.2022 21:32
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
1
3
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Из Rhai Book вы можете Вызвать функцию в пределах области действия вызывающей стороны:

Функции Rhai являются чистыми, что означает, что они зависят от своих аргументов и не имеют доступа к вызывающей среде.

Когда функция обращается к переменной, которая не определена в области видимости этой функции, возникает ошибка оценки.

С помощью специального синтаксиса можно фактически запустить вызов функции в пределах области действия родительского вызывающего объекта, т. е. области действия, в которой выполняется вызов функции, и получить доступ/изменять определенные там переменные.

fn foo(y) {            // function accesses 'x' and 'y', but 'x' is not defined
    x += y;            // 'x' is modified in this function
    let z = 0;         // 'z' is defined in this function's scope
    x
}

let x = 1;             // 'x' is defined here in the parent scope
foo(41);               // error: variable 'x' not found

// Calling a function with a '!' causes it to run within the caller's scope
foo!(41) == 42;        // the function can access and mutate the value of 'x'!
x == 42;               // 'x' is changed!

Таким образом, вы должны быть в состоянии сделать это с помощью direct!().

Другие вопросы по теме