2017-03-28 46 views
2

我想寫一個函數,它需要一個可變字符串並檢查第一個和最後一個字符是否爲"字符。如果是這樣,則應將這兩個字符替換爲反碼字符`。我想出了這個解決方案:用一個字符串中的其他ASCII字符替換某些ASCII字符的簡潔和安全的方法

fn replace_wrapping_char(s: &mut String) { 
    if s.len() > 1 && s.starts_with('"') && s.ends_with('"') { 
     unsafe { 
      let v = s.as_mut_vec(); 
      v[0] = '`' as u8; 
      *v.last_mut().unwrap() = '`' as u8; 
     } 
    } 
} 

這似乎是工作(是的,'`'.is_ascii()返回true),但是它使用unsafe看起來有點醜給我。

有沒有一種安全簡潔的方法來實現我想要的?

+0

https://stackoverflow.com/questions/26544542/modifying-chars-in-a-string-by-index –

+0

你知道,如果整個字符串將是ASCII,或者是它只保證第一個/最後一個字符可能是ASCII碼? – Shepmaster

+0

@Shepmaster我對字符串的ascii-ness一無所知。如果第一個/最後一個字符是''',那麼它們是ascii(顯然是...),否則不能保證。 –

回答

1

下面是該功能的安全縮短版本,雖然它不會提高內存效率。這將創建一個副本並重新分配給定的字符串,因此返回新字符串的純函數原型可能更適合於此。它還依賴於雙引號字符在UTF-8中的大小爲1個字節的事實。

fn replace_wrapping_char(s: &mut String) { 
    if s.len() > 1 && s.starts_with('"') && s.ends_with('"') { 
     *s = format!("`{}`", &s[1 .. s.len()-1]) 
    } 
} 

Playground

+1

Noob問題,但是不會複製整個字符串,然後將其重新分配給's'?難道不應該通過只改變第一個和最後一個字節來做到這一點嗎? – Alec

+0

@Alec Exactly ,這會複製並重新分配字符串,所以我承認這不是解決問題的最佳方法,但是,如果有人可以複製副本,我會保留在這裏 –

+0

@Alec *通過改變第一個和最後一個字節* - 這是OP的解決方案,但它必須是不安全的,因爲類型系統不能保證第一個/最後一個字節e *是* ASCII和*保留* ASCII。 – Shepmaster

相關問題