【问题标题】:Change static string value更改静态字符串值
【发布时间】:2020-12-12 15:47:35
【问题描述】:

我有一个静态可变值:

static mut ADDRESS: &'static str = "";

它是全局的,不在任何函数中。

现在我有一个问题:
我有读取这个值的函数,它们工作正常,但是当我尝试创建从参数更改这个值的函数时 - 它开始哭泣那个值“活得不够长”。

#[no_mangle]
pub unsafe extern fn Java_Rust_setAddress(
    env: JNIEnv,
    _: JClass,
    address: JString
) {
    let input: String = env.get_string(address).expect("Couldn't get java string!").into();
    ADDRESS = &input /Error there/
}

我能用它做什么?在每种情况下传输地址都不是变体,我确实需要一个简单的全局变量。

ADDRESS = input.as_str()

也不行。

但是

ADDRESS = "Something"

效果很好。

【问题讨论】:

  • 您的String 将在您的函数完成后被删除。对它的引用不能放在具有静态生命周期的静态变量中。
  • 这能回答你的问题吗? How do I create a global, mutable singleton?
  • @Aplet123 从变量或变量值中创建 ADDRESS 值对我来说并不重要。我不敢相信 2010 年开发的编程语言和这么大的社区没有我需要的那么简单的功能。
  • 问题在于静态可变数据并不简单。

标签: rust


【解决方案1】:

您的String 将在函数完成后被删除。因此,您不能将引用存储在 static 变量中:

ADDRESS = &input;
       // ^^^^^^ input does not live long enough
       // ADDRESS requires that `input` is borrowed for `'static`
}
// < `input` dropped here while still borrowed by ADDRESS

相反,您需要存储一个全局堆分配的String。有几种方法可以获得全局堆分配变量as explained here。在您的情况下,您可以使用thread_local 全局static 变量并将字符串包装在Cell 中,这提供了可变性:

use std::cell::Cell;

thread_local!(static ADDRESS: Cell<String> = Cell::new("".to_string()));

#[no_mangle]
pub unsafe extern fn Java_Rust_setAddress(
    env: JNIEnv,
    _: JClass,
    address: JString
) {
    let input: String = env.get_string(address).expect("Couldn't get java string!").into();
    ADDRESS.with(|address| address.set(input));
}

【讨论】:

    猜你喜欢
    • 2021-11-12
    • 2019-05-29
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多