小白: Rust 一个编译问题。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
istomyang
V2EX    Rust

小白: Rust 一个编译问题。

  •  
  •   istomyang 2023-01-31 11:04:05 +08:00 2424 次点击
    这是一个创建于 1033 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请问大佬,我下面这个代码有个问题:

    use std::marker::PhantomData; trait T1 { fn f(); } trait T2<A: T1> where A: T1, { fn user(&self) -> A; } struct ImplT2<A> { _marker: PhantomData<A>, } impl<A> T2<A> for ImplT2<A> where A: T1, { fn user(&self) -> A { ImplT1 {} } } struct ImplT1; impl T1 for ImplT1 { fn f() { print!("") } } 

    cargo check 提供的信息:

    error[E0308]: mismatched types --> src/iam/chain/test.rs:23:9 | 18 | impl<A> T2<A> for ImplT2<A> | - this type parameter ... 22 | fn user(&self) -> A { | - expected `A` because of return type 23 | ImplT1 {} | ^^^^^^^^^ expected type parameter `A`, found struct `ImplT1` | = note: expected type parameter `A` found struct `ImplT1` 

    语法检查区并不认为 A 等同于 ImplT1 。

    13 条回复    2023-01-31 22:24:50 +08:00
    nebkad
        1
    nebkad  
       2023-01-31 13:34:36 +08:00
    你可能想要的是 `fn user(&self) -> dyn A`
    istomyang
        2
    istomyang  
    OP
       2023-01-31 15:30:04 +08:00
    @nebkad 谢谢!这样的签名不就导致编译期不能确定 Size 吗?用 Box<T> 可以,但不够优雅。

    PS:我习惯先写接口,用接口确定组织架构关系,然后写实现代码,所以我想是不是姿势不对。然后我看一些标准库和 reqwest 源码,他们的代码组织好像也没有这种习惯(可能我看的东西少)。
    DeWjjj
        3
    DeWjjj  
    PRO
       2023-01-31 15:39:27 +08:00
    我是萌新啊,我看过的问题是。
    你返回的是个 Trait 对象,而 Trait 对象好像在抽象语法树里面生成之后是无法去界定大小的。
    需要使用到 dyn 。
    DeWjjj
        4
    DeWjjj  
    PRO
       2023-01-31 15:41:31 +08:00
    你真的要返回的话,你要开个 BOX 或者用&去用。
    dianqk
        5
    dianqk  
       2023-01-31 16:01:24 +08:00
    你不能在泛型 A 中返回一个具体的类型,如果用的时候是 `ImplT2<ImplTX>` 会导致期望返回 `ImplTX` 而实际返回 `ImplT1`,这不符合约定。(这里不是 Java ,更没有继承)。

    感觉 op 想可以在不同场景下,切换 T1 和 T2 的实现,不知道 https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c63c18f4708f830a22130e5e2297b42d 能不能满足?
    johnli
    6
    johnli  
       2023-01-31 18:14:06 +08:00
    @istomyang 也可以改 `trait T2` 的方法`user` 的返回类型为 `impl T1`, 这个目前只能在 nightly 使用
    icodesign
        7
    icodesign  
       2023-01-31 18:50:37 +08:00
    其中一种办法是如果 T1 的实现是可以枚举的,把他们封装成 enum ,然后返回这个 enum 就行,我看到不少是这么处理的,要么只能返回 Box 了
    nebkad
        8
    nebkad  
       2023-01-31 21:43:12 +08:00
    @istomyang 如果你需要运行时多态而不是编译期多态,但又觉得锁死用 Box 不够优雅,那么你可以试试约束为 DerefMut<Target = dyn T1>
    当然,现在直接这么写是不行的,T1 必须是 Sized
    istomyang
        9
    istomyang  
    OP
       2023-01-31 21:59:44 +08:00
    @DeWjjj 谢谢回复!是的,不满足 Size ,只能用 Box 或者其他智能指针,但总感觉不优雅。
    istomyang
        10
    istomyang  
    OP
       2023-01-31 22:13:28 +08:00
    @DianQK 感谢回复,满足需求,大佬太厉害了,万分感谢。
    istomyang
        11
    istomyang  
    OP
       2023-01-31 22:16:56 +08:00
    @johnli 感谢回复,我用的是 stable ,trait 里不能用 impl 关键词,未来有希望。
    istomyang
        12
    istomyang  
    OP
       2023-01-31 22:18:32 +08:00
    @icodesign 感谢回复!用枚举就有点,,,,很不优雅。
    istomyang
        13
    istomyang  
    OP
       2023-01-31 22:24:50 +08:00
    @nebkad 感谢回复,是的,这个方法也不错,学习到了,谢谢大佬!
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2532 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 11:33 PVG 19:33 LAX 03:33 JFK 06:33
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86