首页 > 解决方案 > Rust 是否具有与 Scala 的 Nothing 类型等效的类型?

问题描述

在 Scala 中,我们可以将未知类型设置为Nothing. 在下面的代码中Remove并将Expire值的类型设置为Nothing.

合并两个集合,其中一个集合 ( putUpdateRemove) 知道值类型,而另一个 ( removeExpire) 值类型未知,将生成一个集合 ( combined),其中值的类型由编译器推断/知道。

sealed trait KeyValue[K, +V]
case class Put[K, V](key: K, value: V) extends KeyValue[K, V]
case class Update[K, V](key: K, value: V) extends KeyValue[K, V]
case class Remove[K](key: K) extends KeyValue[K, Nothing] //Nothing value
case class Expire[K](key: K, time: Long) extends KeyValue[K, Nothing] //Nothing value

object Test {
  // a collection where the type of value is known
  val putUpdateRemove: Seq[KeyValue[Int, Int]] = Seq(Put(1, 1), Update(2, 2), Remove(3))
  // a collection where the type of value is unknown
  val removeExpire: Seq[KeyValue[Int, Nothing]] = Seq(Remove(1), Expire(2, System.currentTimeMillis()))
  //merge the two collections infers the type of value. 
  val combined: Seq[KeyValue[Int, Int]] = putUpdateRemove ++ removeExpire
}

这在 Rust 中可能吗?我希望Never类型会是它。但是下面的代码错误mismatched types expected i32, found !

#![feature(never_type)]

use std::time::SystemTime;

enum KeyValue<K, V> {
    Put { key: K, value: V },
    Update { key: K, value: V },
    Remove { key: K },
    Expire { key: K, time: SystemTime },
}

fn main() {
    let mut put_update_remove: Vec<KeyValue<i32, i32>> =
        vec![KeyValue::Put { key: 1, value: 1 }, KeyValue::Update { key: 2, value: 2 }, KeyValue::Remove { key: 3 }];

    let mut remove_expire: Vec<KeyValue<i32, !>> =
        vec![KeyValue::Remove { key: 1 }, KeyValue::Expire { key: 2, time: SystemTime::now() }];

    put_update_remove.append(&mut remove_expire);
}

标签: rust

解决方案


一个……知道值类型,另一个……值类型未知的结果是一个集合(组合),其中编译器推断/知道值的类型。

我对 Scala 不熟悉,但如果你想有一个由编译器推断的具体类型,那么你可以使用_语法来请求它。您的第二个示例将使用如下编写的类型进行编译, using_和 not !

let mut remove_expire: Vec<KeyValue<i32, _>> = ...

这只是 Rust 类型推断的特定情况的语法,其中类型是部分指定的,而不是完全指定或完全省略的。(它通常与 一起使用Iterator::collect(),您想指定要生成的集合类型但不需要指定项目类型。)

!类型与 完全不同_:它是一种没有值的类型,用于表示函数永远不会返回,或者通常永远无法计算值(程序将遵循其他一些控制流路径) .


推荐阅读