< 返回版块

祐祐 发表于 2021-08-15 14:52

Tags:trait, dyn trait, multiple trait object

我试过了一些奇怪的技巧,as 关键字,Any 的trait,以及其他发法...

请问可以直接或间接让&dyn AB 物件放入func2 吗,这功能应该很重要才对吧。

失去这种写法写面向对向,特别是运用设计模式应该很困难八。

fn main() {

    struct S{}
    impl A for S{}
    impl B for S{}
    impl AB for S{}
    trait A{}
    trait B{}
    trait AB:B+A{}


    fn func1(a:&dyn AB){
        println!("Object B");
        //Error func2(a);
    }
    fn func2(a:&dyn B){
        println!("Object B")
    }
    
    println!("...");
}

Ext Link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=16265df0dc41876c085fd18c527c7632

评论区

写评论
作者 祐祐 2021-08-19 13:10

感謝 johnmave126 😀😀。

--
👇
johnmave126: 因为rust提倡compose而不是inherit,不过目前fat pointer不支持multiple trait object也确实是个问题。

johnmave126 2021-08-19 02:36

因为rust提倡compose而不是inherit,不过目前fat pointer不支持multiple trait object也确实是个问题。

--
👇
swdcgghxa: 不过,更不解的是这种做法在其他程式语言明明是这么常见,可是怎么看起来我用的功能好像很冷门。 难道Rust通常用不着,还是最佳做法不这么用?,阿阿~~想不透该不该...

作者 祐祐 2021-08-18 14:15

不过,更不解的是这种做法在其他程式语言明明是这么常见,可是怎么看起来我用的功能好像很冷门。 难道Rust通常用不着,还是最佳做法不这么用?,阿阿~~想不透该不该...

作者 祐祐 2021-08-18 14:06

这个库怎么实现的太神了,不知道效率会不会降低...?。

我已经试写了一段代码效果还不错。

use cast_trait_object::{dyn_cast, dyn_upcast, DynCastExt};

#[dyn_cast(N)]
#[dyn_upcast]
trait Super1 : N{
    fn run1(&self){
        println!("run1:s1")
    }
}

trait N {
    fn run3(&self){
        println!("run3:n")
    }
}

trait Super2 {
    fn run2(&self){
        println!("run2:s2")
    }
}
#[dyn_cast(Super1)]
#[dyn_cast(Super2)]
#[dyn_upcast]
trait Sub: Super1 + Super2{
    fn run0(&self){
        println!("run0:sub")
    }
}

struct Foo;
impl Foo {
    fn run(&self){
        println!("run_:foo")
    }
}
#[dyn_cast(N)]
#[dyn_upcast]
impl Super1 for Foo {}

impl N for Foo {}

impl Super2 for Foo {}

#[dyn_cast(Super1)]
#[dyn_cast(Super2)]
#[dyn_upcast]
impl Sub for Foo {}

fn main() {
    let foo = &Foo;
    foo.run();
    foo.run0();
    foo.run1();
    foo.run2();
    let sub: &dyn Sub = foo;
    sub.run0();
    let s1: &dyn Super1 = sub.dyn_cast().ok().unwrap();
    s1.run1();
    s1.run3();
    let n: &dyn N = s1.dyn_cast().ok().unwrap();
    n.run3();
    let s2: &dyn Super2 = sub.dyn_cast().ok().unwrap();
    s2.run2();
}

--
👇
johnmave126 这种的? << 😃是阿

johnmave126 2021-08-17 11:12

https://crates.io/crates/cast_trait_object/0.1.1

这种的?

--
👇
swdcgghxa: 各位大神们,还有其他方法吗?

作者 祐祐 2021-08-17 10:15

各位大神们,还有其他方法吗?

作者 祐祐 2021-08-16 03:27

请问如何写这unsafe呢?感恩~~

--
👇
peacess: 可以使用unsafe代码,不需要nightly

peacess 2021-08-15 22:03

可以使用unsafe代码,不需要nightly

viruscamp 2021-08-15 19:20

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=5e66ded709c150d76d13187554a2a076

#![feature(trait_upcasting)]

fn main() {

    struct S{}
    impl A for S{}
    impl B for S{}
    impl AB for S{}
    trait A{}
    trait B{}
    trait AB:B+A{}


    fn func1(a:&dyn AB){
        println!("Object AB");
        func2(a);
    }
    fn func2(a:&dyn B){
        println!("Object B")
    }
    
    println!("...");

    let s = S{};
    func1(&s);
}
作者 祐祐 2021-08-15 16:58

这个我知道只是希望可以动态分发

--
👇
苦瓜小仔: ```RUST #![allow(dead_code)]

fn main() {

struct S{}
impl A for S{}
impl B for S{}
impl AB for S{}
trait A{}
trait B{}
trait AB: B+A{}


fn func1(a: &impl AB){
    println!("Object B");
    func2(a);
}

fn func2(_: &impl B){
    println!("Object B")
}

println!("...");

}

作者 祐祐 2021-08-15 16:56

我该怎么加呢?有不使用nightly方法吗?

--
👇
Cupnfish: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=16265df0dc41876c085fd18c527c7632

试试这个?不过需要nightly开不稳定的feature

苦瓜小仔 2021-08-15 16:11
#![allow(dead_code)]

fn main() {

    struct S{}
    impl A for S{}
    impl B for S{}
    impl AB for S{}
    trait A{}
    trait B{}
    trait AB: B+A{}


    fn func1(a: &impl AB){
        println!("Object B");
        func2(a);
    }

    fn func2(_: &impl B){
        println!("Object B")
    }
    
    println!("...");
}
Cupnfish 2021-08-15 15:07

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=16265df0dc41876c085fd18c527c7632

试试这个?不过需要nightly开不稳定的feature

1 共 13 条评论, 1 页