< 返回版块

祐祐 发表于 2021-08-07 15:13

Tags:trait object, trait,Generic

我如何修正像是 func_dyn1(a: &dyn Ktrait)的型态

真的在这搞了好久了,完全没头绪请求协助😥。

trait Ktrait<T> {}
trait Ltrait {}

fn func_dyn1(a: &dyn Ktrait<dyn Ltrait>) {
    let x = a;
}
fn func_dyn2(a: &dyn Ktrait<&dyn Ltrait>) {
    let x = a;
}

fn main() {
    struct MStruct(String);
    impl Ltrait for MStruct {}
    let ltrait_dyn: &dyn Ltrait = &MStruct("".to_string());

    struct EStruct<T>(T);
    impl<T: Ltrait> Ktrait<T> for EStruct<T> {}

    // Error
    //let t1: &dyn Ktrait<dyn Ltrait> = &EStruct(ltrait_dyn);
    //func_dyn1(t1);

    // Error
    //let t2: &dyn Ktrait<&dyn Ltrait> = &EStruct(ltrait_dyn);
    //func_dyn2(t2);
}

错误资讯很奇怪应该没帮助,但贴一下。

   Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `&dyn Ltrait: Ltrait` is not satisfied
  --> src/main.rs:18:41
   |
18 |     let dt2: &dyn Ktrait<&dyn Ltrait> = &EStruct(ltrait_dyn);
   |                                         -^^^^^^^^^^^^^^^^^^^
   |                                         |
   |                                         the trait `Ltrait` is not implemented for `&dyn Ltrait`
   |                                         help: consider removing the leading `&`-reference
   |
note: required because of the requirements on the impl of `Ktrait<&dyn Ltrait>` for `EStruct<&dyn Ltrait>`
  --> src/main.rs:17:21
   |
17 |     impl<T: Ltrait> Ktrait<T> for EStruct<T> {}
   |                     ^^^^^^^^^     ^^^^^^^^^^
   = note: required for the cast to the object type `dyn Ktrait<&dyn Ltrait>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

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

评论区

写评论
作者 祐祐 2021-08-08 10:04

阿阿太感谢catsalwaysmeow大神,我弄了好久,我就想这样实现,其中技巧长知识了,完全没问题了😃😃😃😃

--
👇
catsalwaysmeow: 代码

&dyn Ltrait没有实现Ltrait,手动实现一下就好了,其它的一些小问题也在代码中注释了。现在好像没有办法方便地构造一个DST<DST>,所以&dyn Ktrait<dyn Ltrait>的部分我没有能够实现。

更进一步,考虑到&dyn Trait的虚函数表(地址)存储在Pointee::Metadata中(胖指针的后半部分),内部的dyn Ltrait的虚函数表又该放在哪里呢?

题主可能遭遇了一个XY Problem,换一种思路或许会更好一些。

作者 祐祐 2021-08-08 09:59

不我就是想看看能不能再泛型中再放入DST,不过你这个想法我没想到,收藏哈哈。

👇
eweca-d: 我觉得可能是你对语法有点误解。我猜你可能是希望让Ktrait只对EStruct<T>,其中Timpl Ltrait的生效。而T是比如i32Estruct则不生效对吧?

catsalwaysmeow 2021-08-07 20:47

代码

&dyn Ltrait没有实现Ltrait,手动实现一下就好了,其它的一些小问题也在代码中注释了。现在好像没有办法方便地构造一个DST<DST>,所以&dyn Ktrait<dyn Ltrait>的部分我没有能够实现。

更进一步,考虑到&dyn Trait的虚函数表(地址)存储在Pointee::Metadata中(胖指针的后半部分),内部的dyn Ltrait的虚函数表又该放在哪里呢?

题主可能遭遇了一个XY Problem,换一种思路或许会更好一些。

eweca-d 2021-08-07 18:05

我觉得可能是你对语法有点误解。我猜你可能是希望让Ktrait只对EStruct<T>,其中Timpl Ltrait的生效。而T是比如i32Estruct则不生效对吧?

如果是我的话,我会这么写:

trait Ktrait {}
trait Ltrait {}

fn func_dyn1(a: &dyn Ktrait) {
    let x = a;
}

fn func_dyn2(a: &dyn Ktrait) {
    let x = a;
}

fn func_dyn3(a: &dyn Ktrait) {
    let x = a;
}

struct MStruct(String);
impl Ltrait for MStruct {}

struct EStruct<T>(T);
impl Ktrait for EStruct<&dyn Ltrait> {}

fn main() {
    let ltrait_dyn: &dyn Ltrait = &MStruct("".to_string());

    let t1 = &EStruct(ltrait_dyn);
    func_dyn1(t1);

    let t2 = &EStruct(ltrait_dyn);
    func_dyn2(t2);

    // Error(the trait `Ktrait` is not implemented for `EStruct<i32>)
    // let t3 = &EStruct(5i32);
    // func_dyn3(t3);
}

至于你这么写为什么会这么报错,我一时也理不清,等一个大神说说吧。

munpf 2021-08-07 17:24

你已经用dyn Ltrait了,Ktrait和EStruct就不需要用泛型了吧。

1 共 5 条评论, 1 页