gpt4 book ai didi

string - 在接口(interface)上使用 Into - Vec> 的零成本?

转载 作者:行者123 更新时间:2023-11-29 08:07:19 26 4
gpt4 key购买 nike

我正在使用 Into<String>作为允许创建 Person 的参数类型与例如str以及拥有的String

pub struct Person {
pub first_name: String,
pub last_name: String,
}

impl Person {
pub fn new<S>(first_name: S, last_name: S) -> Self
where S: Into<String>
{
Self {
first_name: first_name.into(),
last_name: last_name.into(),
}
}
}

据我所知,由于单态性,这在运行时是零成本。

现在,我确定这不是零成本:

pub struct Person {
pub first_name: String,
pub middle_names: Vec<String>,
pub last_name: String,
}

impl Person {
pub fn new<S>(first_name: S, middle_names: Vec<S>, last_name: S) -> Self
where S: Into<String>
{
let middle_names: Vec<String> = middle_names.into_iter().map(|s| s.into()).collect();

Self {
first_name: first_name.into(),
middle_names,
last_name: last_name.into(),
}
}
}

我想知道我是否能以某种方式让这一切“零成本”。 Vec意味着数据在堆上,但也许我可以替换 Vec与一些其他有用的数据结构甚至切片。

有什么想法吗?

最佳答案

以下是我能想到的一些解决方案。

实现两个不同的构造函数

你可以实现两个独立的构造函数——一个用于 S = String和一个 S: Into<String> .如果人们关心优化,他们将不得不为这两种情况使用不同的名称。

忽略问题

我不知道您的实际用例,但这看起来不太可能成为您应用程序的性能瓶颈,因此您可以简单地接受微小的开销。不会复制字符串数据本身,只会复制元数据(指针、长度和容量),因此开销很小。

使用特化

Rust nightly 部分支持 specialization of traits ,因此您可以为重叠的类型集实现特征。这允许您实现 IntoStringVec特化为 String 的特质什么都不做

#![feature(specialization)]

trait IntoStringVec: Sized {
fn into_string_vec(v: Vec<Self>) -> Vec<String>;
}

impl IntoStringVec for String {
fn into_string_vec(v: Vec<String>) -> Vec<String> {
v
}
}

impl<T: Into<String>> IntoStringVec for T {
default fn into_string_vec(v: Vec<Self>) -> Vec<String> {
v.into_iter().map(Into::into).collect()
}
}

此解决方案需要每晚使用 Rust。

使用不安全代码进行就地转换

对于 size_of::<S>() == size_of::<String>() 的情况,您可以实现向量的就地转换和 align_of::<S>() >= align_of::<String>() .手动执行此操作有点棘手,因此我建议您找到一些实现此功能的 crate ,例如map_in_place crate .


我个人会忽略该问题,直到它成为一个实际问题,如果确实如此,则采用第一个解决方案。

关于string - 在接口(interface)上使用 Into<String> - Vec<Into<String>> 的零成本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53580258/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com