V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
LeeReamond
V2EX  ›  问与答

Rust 泛型求助

  •  
  •   LeeReamond · 2021-03-02 18:12:10 +08:00 via Android · 1024 次点击
    这是一个创建于 1150 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如题,需求是现有若干二维数组,具体表现形式为 Vec<[T;N]>

    数组比较动态,T 可以是 i32 或者 f64,N 需要在运行时确定,确定后不会再更改。现在想实现一个函数,让数组传递进去以后,自动扫描是否有非法值(负数即非法),一旦出现,从下一行补位替换非法值。


    为了代码复用,想让所有类型,长度的数组都能共用一个方法。折腾了半天没搞明白怎么写,求助
    8 条回复    2021-03-03 05:45:44 +08:00
    gfreezy
        1
    gfreezy  
       2021-03-02 18:30:34 +08:00
    写个 macro,范型解决不了这个问题吧
    nbndco
        2
    nbndco  
       2021-03-02 18:36:05 +08:00
    https://crates.io/crates/num,Vec 长度可变并不是类型签名,不需要处理 N
    codehz
        3
    codehz  
       2021-03-02 18:44:44 +08:00 via Android
    处理 slice 就好了啊。。。
    不过现在 min const generic 已经 stable 了,写<const N: usize>的泛型也可以,但是意义不明,不如直接 slice &mut [T]
    LeeReamond
        4
    LeeReamond  
    OP
       2021-03-02 19:23:38 +08:00 via Android
    @codehz 我试了一下那个 const 的写法不支持,我是新装的 rust 。slice 那个看不懂,初学 rust,大佬能提供一个最小实现吗
    codehz
        5
    codehz  
       2021-03-02 21:35:26 +08:00
    @LeeReamond #4 看了一眼,还差一点 stable,几天之后就可以了(现在可以用 beta 版本过编译
    https://play.rust-lang.org/?version=beta&mode=debug&edition=2018
    codehz
        6
    codehz  
       2021-03-02 21:49:07 +08:00
    slice 的解决方案(算法没实现,只是随便写了一个判断赋值以确定能读写,你自己解决)
    https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=52572dfc88bd38847f4f3adb49e982a2
    const generic 的解决方案
    https://play.rust-lang.org/?version=beta&mode=debug&edition=2018&gist=f5223859a949a5b4de1278aad883cea2
    (同样没实现算法,只是测试能读写
    LeeReamond
        7
    LeeReamond  
    OP
       2021-03-03 05:08:16 +08:00
    @codehz 感谢代码,我在英文社区中的帖子得到了相似的回复,使用 AsMut 可以抽象出接受任意长度数组输入的版本,它的问题在于无法接受任意类型数组(比如[i32]和[f64]不能同时输入),而如果使用泛型替代的话,比如 AsMut<[T]>,则产生了后续 T 的所有实现都要 trait 的问题。

    英文老哥给出的设计哲学是,虽然最终可以实现,但建议不要这么组织代码,由于 rust 没有一个针对全体数字类型的抽象,一旦采用 T 接受任意类型的输入,你需要使用 trait 约束其所有实现细节,并由于其仅约束 trait,可能带来输入不安全的问题(同性状下完全不相干的类型输入)。所以无论采用 const 的方式还是 asmut 的方式,输入类型最好唯一,并以宏来解决代码复用问题。

    无论如何感谢你们的回复。
    codehz
        8
    codehz  
       2021-03-03 05:45:44 +08:00
    (也不是不可以,至少上面那个例子里可以 https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=588978a0660307e665d75ba56ba25a9c
    抽象可以针对行为而非具体类型进行,里面的判断也可以换成传递一个函数(这里肯定能被 inline,所以不用担心损耗)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4458 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 05:34 · PVG 13:34 · LAX 22:34 · JFK 01:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.