我如何设计一个可以对 `Self:!Copy` 和 `Self=&mut[S]` 进行操作的通用特征

问题描述

我正在尝试实现一些自定义特征,在某些情况下,我正在为 &mut [T] 实现。问题在于 trait 方法使用 &self,这会导致双重引用。我不能使用普通的 self,否则我将无法实现 T:!copy。最简单的例子是

fn llama(message: &&mut [char])
{
    (*message)[0] = 'b';
}

fn main()
{
    let mut message: Vec<char> = "Rust".chars().collect();
    let m2:&mut [char] = &mut message;

    llama(&m2);
}

这给了我

error[E0594]: cannot assign to `message[_]` which is behind a `&` reference

让我走到这一步的一个更复杂的例子(仍然没有我正在开发的库那么复杂)是

rust playground

use std::fmt::{display,Write};
use std::iter::FromIterator;

trait Wood {
    type T: display;
    fn drill(&self) -> Self::T;
}

struct Orange {
    val: i32,}

impl Wood for Orange {
    type T = String;

    fn drill(&self) -> Self::T {
        format!("{}w",self.val)
    }
}

impl<S> Wood for Vec<S>
where
    S: Wood,{
    type T = String;

    fn drill(&self) -> Self::T {
        let slice: &[S] = self.as_slice();
        let mut rval: Self::T = <&[S] as Wood>::drill(&slice);
        rval.push('v');
        rval
    }
}

impl<S> Wood for &[S]
where
    S: Wood,{
    type T = String;

    fn drill(&self) -> Self::T {
        let mut rval: String = String::new();
        for o in *self {
            write!(rval,"{},",<S as Wood>::drill(o)).unwrap();
        }
        rval
    }
}

pub fn pants(x: &mut [char]) {
    for ch in x {
        if ch.is_lowercase() {
            *ch = ch.to_uppercase().next().unwrap();
        } else if ch.is_uppercase() {
            *ch = ch.to_lowercase().next().unwrap();
        }
    }
}

impl Wood for &mut [char] {
    type T = String;

    fn drill(&self) -> Self::T {
        //pants(*self);
        (*self)[0] = 'n';
        String::from_iter(self.iter())
    }
}

fn main() {
    let oranges = (1..5).map(|i| Orange { val: i }).collect::<Vec<_>>();

    println!("{}",oranges.drill());

    let z: &[Orange] = &oranges;
    println!("{}",z.drill());

    let mut message:Vec<_> = "Rust".chars().collect();
    let message:&mut [char] = &mut message;
    println!("{}",message.drill());
    println!("{}",message.drill());

    let m2:&&mut [char] = &message;
    (*m2)[0] = 'n';
}

当特征使用 &self 时,我得到 E0594,但是当它使用 self 时,我无法为 &[T:!copy] 实现它,因为我得到了 {{1 }}。我如何在这个 Scylla 和 Charybdis 之间移动?

为了帮助怀疑 XY 问题的人,我试图做的是创建一个特征,我可以使用它来将 Rust 对象转换为 error[E0507]: cannot move out of `*o` which is behind a shared reference 板条箱的 JValue。该代码看起来像

jni

它被用于生成代码的过程宏中

impl<'a: 'b,'b> ConvertRustToJValue<'a,'b> for &[i16] {
    type T = AutoLocal<'a,'b>;
    fn into_temporary(self,je: &'b jnienv<'a>) -> Result<AutoLocal<'a,'b>,jni::errors::Error> {
        let rval: jshortArray = je.new_short_array(self.len() as jsize)?;
        je.set_short_array_region(rval,self)?;

        Ok(AutoLocal::new(je,JObject::from(rval)))
    }
    fn temporary_into_jvalue(tmp: &AutoLocal<'a,'b>) -> JValue<'a> {
        JValue::from(tmp.as_obj())
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)