我有一个由几个变体组成的枚举:

enum Foo {
  A,
  B,
  C,
}

我有一个函数,里面有if和Match循环,它的所有分支都是发散的:

fn my_function() -> i32 {
  // some vars
  for ... in ... { // also may be `while` or `loop`
    // some code
    if some_condition {
      let foo: Foo = ...;
      match foo {
        Foo::A => { return 42 }
        Foo::B => { continue }
        Foo::C => {
          // do something with vars
          continue
        }
      }
      // this place is currently unreachable
      // and must **always** be **totally** unreachable
      // because the code after `if` must never execute in this(`some_condition`) case
    }
    // some code
  }
}

但随着将来的一些更改,我可能会向枚举添加新的变体(S),所以我想compilation次判断这条线是不是无法到达的.我觉得这应该是可能的,但我不知道怎么做.

《之前的艺术》:

  • unreachable!对我不起作用,因为这是一个运行时判断,在这段代码执行之前需要很多时间,而且不能保证它会命中这个unreachable,因为在到达那里的过程中涉及到rng.
  • compile_error!为cfg标志,在这种情况下,显然总是给出错误,而不是依赖于该位置的可达性.
  • !-type -不确定是否可以使用never-type来解决这个问题.

如果有像const_unreachable!soft_compile_error!这样的东西来填补这个确切的场景,当且仅当存在导致编译错误的执行路径时,就好了……

那么有什么可能的解决方案(包括每晚Rust 和任何特征)来解决这个问题呢?

推荐答案

在晚上,你可以用"Never"类型将match的结果影响到一个变量:

#![feature(never_type)]

enum Foo {
  A,
  B,
}

fn main() {
    let x = Foo::A;
    let _: ! = match x {
        Foo::A => { println!("A"); return; }
        Foo::B => { println!("B"); /* Forgot `return` here */ }
    };
}

Playground

提供:

error[E0308]: mismatched types
  --> src/main.rs:12:19
   |
12 | Foo::B => { println!("B"); /* Forgot `return` here */ }
   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `!`, found `()`
   |
   = note:   expected type `!`
           found unit type `()` 

正如@Rodrigo指出的,在Never类型稳定下来之前,使用std::convert::Infallible可以在稳定 rust 色上实现相同的效果:

enum Foo {
  A,
  B,
}

fn main() {
    let x = Foo::A;
    let _: std::convert::Infallible = match x {
        Foo::A => { println!("A"); return; }
        Foo::B => { println!("B"); /* Forgot `return` here */ }
    };
}

Playground

Rust相关问答推荐

如何初始化match声明中的两个变量而不会激怒borrow 判断器?

将JSON密钥转换为Polars DataFrame

如何在Rust中实现Functor trait?

带扫描的铁 rust 使用滤镜

Gtk4-rs:将监视器作为gdk::monitor获取,而不是作为glib::对象获取

`Pin`有没有不涉及不安全代码的目的?

从未排序的链表中删除重复项的铁 rust 代码在ELSE分支的低级上做了什么?

如何将实现多个特征的 struct 传递给接受这些特征为&;mut?

try 实现线程安全的缓存

可选包装枚举的反序列化

返回迭代器考虑静态生命周期类型

当没有实际结果时,如何在 Rust 中强制执行错误处理?

我可以用 Rust 编写一个不可变变量

如何使用 Bincode 在 Rust 中序列化 Enum,同时保留 Enum 判别式而不是索引?

pyO3 和 Panics

将原始可变指针传递给 C FFI 后出现意外值

Rust 引用元组和引用元组

如何在 Rust 中返回通用 struct

如何在 Rust 中创建最后一个元素是可变长度数组的 struct ?

在 Rust 中获得准确时间的正确方法?