当前位置:  开发笔记 > 后端 > 正文

我可以在两个特征之间施展吗?

如何解决《我可以在两个特征之间施展吗?》经验,为你挑选了1个好方法。



1> Shepmaster..:

没有.没有办法在两个不相关的特征之间施展.要理解原因,我们必须了解如何实现特征对象.首先,让我们来看看TraitObject.

TraitObject反映了特质对象的实际实现方式.它们由两个指针组成:datavtable.该data值只是对原始对象的引用:

#![feature(raw)]

trait Foo {}
impl Foo for u8 {}

use std::{raw, mem};

fn main() {
    let i = 42u8;
    let t = &i as &Foo;
    let to: raw::TraitObject = unsafe { mem::transmute(t) };

    println!("{:p}", to.data);
    println!("{:p}", &i);
}

vtable指向函数指针表.此表包含对每个实现的特征方法的引用,这些方法按一些编译器内部方式排序.

// For this hypothetical input
trait Foo {
    fn one(&self);
}

impl Foo for u8 {
    fn one(&self) { println!("u8!") }
}

// The table is something like this pseudocode
const FOO_U8_VTABLE = [impl_of_foo_u8_one];

因此,特征对象知道指向数据的指针以及指向构成该特征的方法列表的指针.根据这些信息,无法获得任何其他数据.

好吧,几乎没办法.正如您可能猜到的,您可以向vtable添加一个返回不同特征对象的方法.在计算机科学中,所有问题都可以通过添加另一层间接(除了太多的间接层)来解决.

但是不能将这data部分TraitObject转化为结构

不安全,没有.特征对象不包含有关原始类型的信息.它只是一个包含内存中地址的原始指针.您可能会将其无法安全转换为a &Foo或a &u8或a &(),但编译器和运行时数据都不知道它最初的具体类型.

Any特征实际上也是通过跟踪原始结构的类型ID来实现的.如果要求引用正确的类型,则特征将为您转换数据指针.

是否有一种模式,而不是我用我的FooOrBar特性描述的模式来处理这样的情况,我们需要迭代一堆特征对象,但是它们中的一些稍微不同?

如果您拥有这些特征,那么您可以添加as_fooBar特征,反之亦然.

您可以创建一个包含a Box或a Box和then模式匹配的枚举.

您可以将主体移动bar到该foo实现的主体中.

您可以实现第三个特性Quux,其中呼叫::quux呼叫Foo::foo::quux呼叫Bar::foo后跟呼叫Bar::bar.

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有