Exercise: Replace String by &str

I'm working on the following exercise:

and I would like to optimize the memory by changing String to &str. I tried the following without success:

use std::collections::HashMap;

const DNA_NUCLEOTIDES: &str = "GCTA";
const RNA_NUCLEOTIDES: &str = "CGAU";

#[derive(Debug, PartialEq)]
pub struct DNA<'a>(&'a str);

#[derive(Debug, PartialEq)]
pub struct RNA<'a>(&'a str);

impl<'a> DNA<'a> {
    pub fn new(dna: &str) -> Result<DNA, usize> {
        match dna.chars().position(|x| !DNA_NUCLEOTIDES.contains(x)) {
            Some(index) => Err(index),
            _ => Ok(DNA(dna.into())),
        }
    }

    pub fn into_rna(self) -> RNA<'a> {
        let transform: HashMap<char, char> = DNA_NUCLEOTIDES
            .chars()
            .zip(RNA_NUCLEOTIDES.chars())
            .collect();
        let s: String = self.0.chars().map(|x| transform[&x]).collect();

        // error[E0515]: cannot return value referencing local variable `s`
        RNA(&s)
    }
}

impl RNA<'_> {
    pub fn new(rna: &str) -> Result<RNA, usize> {
        match rna.chars().position(|x| !RNA_NUCLEOTIDES.contains(x)) {
            Some(index) => Err(index),
            _ => Ok(RNA(rna.into())),
        }
    }
}

Is that possible?

Actually, I don't want to replace self.0 by another string. I simply want to "mutate" the characters, even though they are immutable. Is it possible to do something like this?

fn main() {
    let s = "You shall not pass!";

    // performs some insecure operations
    // ..
    // ..

    assert_eq!(s, "I passed, he he he.")
}

No, you cannot mutate a value if type T if you have a shared reference to T (&T), no matter what.

It's not strictly true that you can't mutate a T through a shared reference (for example, you can mutate a value of &RefCell<String> - it has interior mutability.) However, if you need to mutate it you shouldn't be taking a &str. RNA should just contain a String, given it needs to own new data. Having it contain a &str isn't really an optimization, since the new String you're allocating has to exist somewhere, so it might as well be owned by RNA.

That isn't what I said, you can't mutate T in &T, if you have some other structure, RefCell, in between, then you can mutate T, but this requires you to go through UnsafeCell at some point down the line. Atomics, Cell, RefCell, Mutex, RwLock, all fall into this category. I guess what I mean is you can't mutate T directly.

In any case, str does not fall into the category of types that can change behind a shated reference.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.