💭
[Rust]Stringでtake的な処理[memo]
初投稿テストも兼ねて、ちょっといろいろ実装しているときに、引っかかったので解決法を。
やりたいこと
String型変数aの文字列を空にして、その値を返す
実現コード
事前に変数aがmutableで参照できることを前提に、
{
let mut b = String::new();
std::mem::swap(&mut a, &mut b);
b
}
という形で記述する。
追記: core::mem::takeでできました。WAO。
macroコード
いちいち上のようなコードを作成するのもあれですし、かといってクレートにグローバルな関数を書くのもなーと思ったので、以下のようなmacroを組んで使っています。
#[macro_export]
/// Takes string inner.
macro_rules! take_string {
($var:ident) => {{
let mut empty = String::new();
std::mem::swap(&mut $var, &mut empty);
empty
}};
($var:expr) => {{
let mut empty = String::new();
std::mem::swap(&mut $var, &mut empty);
empty
}};
}
追記: core::mem::takeでできることが分かったので、
#[macro_export]
/// Takes string inner.
macro_rules! take {
($var:ident) => {
core::mem::take(&mut $var)
};
($var:expr) => {{
core::mem::take(&mut $var)
}};
}
という感じに修正。
もしくはもう、use core::mem::take;したらいいかなと思っています。
やっていること
空の文字列を持つ変数を作成し、std::mem::swapで変数の値を入れ替えた(追記前)。
追記後: core::mem::take関数を利用してOptionにおけるtakeのようなことをした。
あれこれ
Stringに組み込みでtakeほしいなって思ったり。というか、Zenn割と書きやすいですね。重くないし。
Discussion