You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用extendr:Rust克隆R字符串后原变量仍被修改的原因

问题原因与解决办法

原因

你调用Strings::clone()后原R变量s仍被修改,核心问题在于extendr的clone()是对R字符向量的浅拷贝:它仅复制了向量的容器结构,但没有创建元素的独立副本。加上R的字符向量底层依赖全局字符串池的指针,用set_elt修改克隆对象时,会意外绕过R的写时复制机制,导致原向量的元素指针被修改。

解决方案

不要依赖clone(),手动构建全新的字符向量,彻底脱离原向量的引用:

#[extendr]
fn strings_elt(x: Strings) -> Strings {
    x.iter()
        .enumerate()
        .map(|(i, s)| {
            if i == 0 {
                // 替换第一个元素为AAA
                "AAA".into()
            } else {
                // 保留其他元素(NA则返回NA_STRING)
                s.cloned().unwrap_or_else(|| NA_STRING.into())
            }
        })
        .collect()
}

验证效果

运行修改后的代码:

library(rextendr)

rust_source(code = '
#[extendr]
fn strings_elt(x: Strings) -> Strings {
    x.iter()
        .enumerate()
        .map(|(i, s)| {
            if i == 0 {
                "AAA".into()
            } else {
                s.cloned().unwrap_or_else(|| NA_STRING.into())
            }
        })
        .collect()
}
')

s <- c("aaa", NA, "bbb")
s1 <- strings_elt(s)
s1   # 输出:"AAA" NA    "bbb"
s    # 输出:"aaa" NA    "bbb" 原变量未被修改

内容的提问来源于stack exchange,提问作者GL_Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 14:03:18