< 返回版块

GuangGuo 发表于 2022-12-09 13:55

type Foo struct {
    header Header
}

type Header interface {}

type AudioHeader interface {
    Header
    Audio() error
}

type VideoHeader interface {
    Header
    Video() error
}

func bar() error {
    ...
    // 假设有了一个 Header 类型的 header
    ah := header.(AudioHeader)
    ah.Audio()

    vh := header.(VideoHeader)
    vh.Video()
    ...
}

大体上的意思是, 我想用一个 header 去存储多种 Header trait, 我能想到最接近的是使用 enum.

enum Header {
    AudioHeader,
    VideoHeader,
}

trait Audio {}
trait Video {}

impl Audio for Header::AudioHeader {} // 报错, 因为 Header::AudioHeader 不是 type

Rust 的trait 确实也可以继承, 比如

trait A {}

trait B: A {}

trait C: A {}

但是我印象里没有能用 trait A 断言到 trait B 或 triat C 的说法.

特此请教一下, Rust 处理这种类型断言的情况有什么好的办法吗?

评论区

写评论
作者 GuangGuo 2022-12-09 20:31

多谢多谢!

--
👇
fakeshadow: ``` // nightly #![feature(provide_any)] fn main() { use std::any::{request_ref, request_value, Demand, Provider};

struct Foo;

impl Provider for Foo {
    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
        demand.provide_ref::<str>("996").provide_value::<i32>(251);
    }
}

let foo = &Foo as &dyn Provider;

assert_eq!(request_ref::<str>(foo), Some("996"));
assert_eq!(request_value::<i32>(foo), Some(251));

}

// stable fn main() { use std::any::Any;

struct Foo;
struct Bar;

let foo = &Foo as &dyn Any;
let bar = Box::new(Bar) as Box<dyn Any>;

assert!(foo.downcast_ref::<Bar>().is_none());
let Some(foo) = foo.downcast_ref::<Foo>() else { unreachable!() };

assert!(bar.downcast_ref::<Foo>().is_none());
let Some(foo) = bar.downcast_ref::<Bar>() else { unreachable!() };

}

stable的直接,nightly的扩展能力强,自选一个就好
作者 GuangGuo 2022-12-09 20:30

多谢多谢!

--
👇
songzhi: ```rust struct AudioHeader {} impl xx for AudioHeader {}

struct VideoHeader {} impl xx for VideoHeader {}

enum Header { Audio(AudioHeader), Video(VideoHeader), }

fakeshadow 2022-12-09 18:12
// nightly
#![feature(provide_any)]
fn main() {
    use std::any::{request_ref, request_value, Demand, Provider};

    struct Foo;

    impl Provider for Foo {
        fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
            demand.provide_ref::<str>("996").provide_value::<i32>(251);
        }
    }

    let foo = &Foo as &dyn Provider;

    assert_eq!(request_ref::<str>(foo), Some("996"));
    assert_eq!(request_value::<i32>(foo), Some(251));
}

// stable
fn main() {
    use std::any::Any;

    struct Foo;
    struct Bar;

    let foo = &Foo as &dyn Any;
    let bar = Box::new(Bar) as Box<dyn Any>;

    assert!(foo.downcast_ref::<Bar>().is_none());
    let Some(foo) = foo.downcast_ref::<Foo>() else { unreachable!() };

    assert!(bar.downcast_ref::<Foo>().is_none());
    let Some(foo) = bar.downcast_ref::<Bar>() else { unreachable!() };
}

stable的直接,nightly的扩展能力强,自选一个就好

songzhi 2022-12-09 17:54
struct AudioHeader {}
impl xx for AudioHeader {}

struct VideoHeader {}
impl xx for VideoHeader {}

enum Header {
    Audio(AudioHeader),
    Video(VideoHeader),
}

作者 GuangGuo 2022-12-09 17:20

多谢多谢!

--
👇
ManonLoki: 虽然不太熟悉 但是记忆中有个 Any类型 可以用于断言

ManonLoki 2022-12-09 16:33

虽然不太熟悉 但是记忆中有个 Any类型 可以用于断言

1 共 6 条评论, 1 页