gpt4 book ai didi

reference - 为什么 Borrow trait 要求借用的类型是引用?

转载 作者:行者123 更新时间:2023-11-29 07:48:44 25 4
gpt4 key购买 nike

想象一些事件源,它产生以枚举表示的事件。当然,为了获得最佳效率,这个生产者是零拷贝的,即它返回对其内部缓冲区的引用:

enum Variant<'a> {
Nothing,
SomeInt(u64),
SomeBytes(&'a [u8])
}

impl Producer {
fn next(&'a mut self) -> Variant<'a> { ... }
}

这对于不需要前瞻或回溯的消费者来说非常好,但有时需要保存一些事件序列。因此,我们的 Variant类型变为通用:

enum Variant<BytesT> {
Nothing,
SomeInt(u64),
SomeBytes(BytesT)
}

type OwnedVariant = Variant<Vec<u8>>;
type BorrowedVariant<'a> = Variant<&'a [u8]>;

在这里,我们最终得到两种具有“所有者-引用”关系的类型,这类似于对 Vec<T> - &[T] , String - &str .文档建议内置特征 BorrowToOwned除了细微的差别外,它只提供所需的内容:

trait Borrow<Borrowed: ?Sized> {
fn borrow(&self) -> &Borrowed;
// this: -----------^
}

pub trait ToOwned {
type Owned: Borrow<Self>;
fn to_owned(&self) -> Self::Owned;
}

borrow 的结果必须是对某物的引用BorrowedVariant<'a>显然不是。删除这个要求解决了这个问题(这里,名称以 alt 为前缀,以强调这是一个替代接口(interface)的事实):

trait AltBorrow<'a, AltBorrowed> {
fn alt_borrow(&'a self) -> AltBorrowed;
}

trait AltToOwned<'a> {
type AltOwned: AltBorrow<'a, Self>;
fn alt_to_owned(&'a self) -> Self::AltOwned;
}

然后可以为标准类型实现此特征,例如Vec :

impl<'a, T> AltBorrow<'a, &'a [T]> for Vec<T> {
fn alt_borrow(&'a self) -> &'a [T] {
self.as_slice()
}
}

impl<'a, T> AltToOwned<'a> for &'a [T]
where T: Clone
{
type AltOwned = Vec<T>;

fn alt_to_owned(&'a self) -> Vec<T> {
self.to_vec()
}
}

以及 Variant有问题的枚举:

impl<'a> AltBorrow<'a, BorrowedVariant<'a>> for OwnedVariant {
fn alt_borrow(&'a self) -> BorrowedVariant<'a> {
match self {
&Variant::Nothing => Variant::Nothing,
&Variant::SomeInt(value) => Variant::SomeInt(value),
&Variant::SomeBytes(ref value) => Variant::SomeBytes(value.alt_borrow()),
}
}
}

impl<'a> AltToOwned<'a> for BorrowedVariant<'a> {
type AltOwned = OwnedVariant;

fn alt_to_owned(&'a self) -> OwnedVariant {
match self {
&Variant::Nothing => Variant::Nothing,
&Variant::SomeInt(value) => Variant::SomeInt(value),
&Variant::SomeBytes(value) => Variant::SomeBytes(value.alt_to_owned()),
}
}
}

最后是问题:

  1. 我是否滥用了原件 Borrow/ToOwned概念?我应该使用其他方法来实现这一目标吗?
  2. 如果不是,那么 std::borrow 中当前不太通用的接口(interface)的原因是什么?可能是首选?

This example on Rust playpen

最佳答案

得到 some explanation在#rust IRC 上。

来自 aturon:

the short answer is: we'd need higher-kinded types (HKT) to do better here; it should be possible to smoothly "upgrade" to HKT later on, though

(this is a pattern that's come up a few places in the standard library)

(lifting the lifetime to the trait level is a way of encoding HKT, but makes it significantly more awkward to use the trait)

来自 blus:

I like your question. That kind of lifetime in a trait hasn't been explored enough IMObut it also has a known bug in the borrow checker right now

关于reference - 为什么 Borrow trait 要求借用的类型是引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30083833/

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