#string #buffer #concat

str-cat

高效地连接字符串,无额外副作用

5个版本

0.2.0 2023年3月2日
0.1.3 2023年2月28日
0.1.2 2023年2月24日
0.1.1 2023年2月24日
0.1.0 2023年2月24日

#267 in 值格式化

BSD-3-Clause

12KB
109

str-cat

此crate提供了宏,可以高效地连接字符串,无额外副作用。

GitHub Workflow Status docs.rs

文档


lib.rs:

此crate提供了宏,可以高效地连接字符串,无额外副作用。

使用方法

基本用法

use str_cat::str_cat;

let s = str_cat!("Hello", " ", "World", "!");
assert_eq!(s, "Hello World!");

大致相当于

let mut s = String::with_capacity("Hello".len() + " ".len() + "World".len() + "!".len());
s.push_str("Hello");
s.push_str(" ");
s.push_str("World");
s.push_str("!");

无额外副作用

该宏运行无额外副作用,这意味着所有相关的表达式只计算一次。

let mut get_world_calls = 0;
let mut get_world = || {
    get_world_calls += 1;
    "World"
};
let s = str_cat!("Hello", " ", get_world(), "!");
assert_eq!(s, "Hello World!");
assert_eq!(get_world_calls, 1);

大致相当于

let world = get_world(); // evaluate the expression and store it for later use
let mut s = String::with_capacity("Hello".len() + " ".len() + world.len() + "!".len());
s.push_str("Hello");
s.push_str(" ");
s.push_str(&world);
s.push_str("!");

追加到现有字符串

let mut s = "Hello".to_owned();
str_cat!(&mut s; " ", "World!");
assert_eq!(s, "Hello World!");

重用现有分配

let mut s = "Hello World!".to_owned();
let ptr = s.as_ptr();
let cap = s.capacity();

s.clear();
str_cat!(&mut s; "Hello");
assert_eq!(s, "Hello");
// Did not grow
assert_eq!(s.as_ptr(), ptr);
assert_eq!(s.capacity(), cap);

自定义最小容量

let s = str_cat!(String::with_capacity(16); "foo", "bar");
assert_eq!(s, "foobar");
assert!(s.capacity() >= 16);

参数类型

当可以避免显式调用 .to_string() 时,使用 format! 应该更简单、更高效。当需要将任何可以解引用到 str 的表达式连接起来时,它都适用。

// Just an example. It's better to use `format!` in this case.
let s = str_cat!(
    "Hello".to_owned(),
    Box::new(" "),
    ['W', 'o', 'r', 'l', 'd'].iter().collect::<String>(),
    '!'.to_string(),
    123456.to_string(),
);
assert_eq!(s, "Hello World!123456");

隐式借用

就像 format!println! 一样,str_cat 会自动为您借用参数,因此您不需要自己输入那个 &

let world = "World!".to_owned();
let s = str_cat!("Hello ", world); // no need for `&`
assert_eq!(s, "Hello World!");
assert_eq!(world, "World!"); // not moved, still valid

变体

还有针对 PathBufOsStringVec 的变体。

use str_cat::os_str_cat;

// Works for anything that implements AsRef<OsStr>.
let s = os_str_cat!(
    OsStr::new("Hello"),
    OsStr::new(" ").to_owned(),
    Path::new("World"),
    "!",
);
assert_eq!(s, OsStr::new("Hello World!"));

无运行时依赖