【问题标题】:What is the Rust equivalent of Scala's value classes?Scala 的值类的 Rust 等价物是什么?
【发布时间】:2018-01-27 12:54:17
【问题描述】:

Scala's value classes 提供了一种在不分配运行时对象(Rust 情况下为结构)的情况下使用类型系统的方法。我正在寻找 Rust 中的等价物。

我想介绍的用例是传递一个表示 URI 的字符串,方法是使用 Uri 而不是 String 之类的注释相关签名,并且理想情况下,在 @ 时使用此 Uri预计为 987654325@。所有这一切都以最小的开销。

一个明显的解决方案是使用具有一个字段的结构:

struct Uri { val: String }

这有一个缺点是使用有点尴尬,在预期 String 的地方是不可接受的,我不确定它的开销。

Rust 中是否有类似于 Scala 的值类的东西?是否有其他机制可以促进这个用例?

【问题讨论】:

  • 您可以尝试使用类型别名type Uri = String,但类型别名不能被视为类似于Scala 的值类。
  • @EvilTak 类型别名不能用于区分 Uri 和 String。

标签: rust


【解决方案1】:

我相信您正在寻找的是“强类型系统”。在 Rust 中,它用一个具有一个字段(newtype)的元组结构表示:

struct Uri(pub String);

这会创建一个开销最小的强类型。我想说这只是为编译器创建了一个标记,即这种类型是Uri,仅此而已。由于这是一个强类型,你不能简单地将String 传递给它并从中获取String,你必须手动进行转换。

Simple exampleString 之上为您提供了一个强类型:

struct Uri(pub String);

fn takes_uri(uri: Uri) {
    println!("URI: {}", uri.0);
}

fn takes_string(uri: String) {
    println!("String: {}", uri);
}

fn main() {
    let uri = Uri("https://stackoverflow.com".to_owned());
    takes_uri(uri);
    // takes_string(uri); // This does not compile
}

强类型的关键是你不能隐式转换它们,所以这需要代码编写者编写显式代码。

【讨论】:

  • 您能多谈谈反对隐式强制转换的理由吗?我倾向于使用 FromInto 特征进行隐式转换。
  • 在某些情况下,您应该添加一个解决方案“当需要 String 时使用此 Uri”。
  • @DominykasMostauskis 使用From / Into 将是显式,因为您必须在某处输入代码.intoUri::from。这明确地标记了转换位置(我同意这是一件好事)。
  • @DominykasMostauski 强类型的大部分要点是在不增加内部表示开销的情况下拥有语义上不同的类型。隐式转换有点违背这一点;但话又说回来,这取决于你到底想做什么。
  • FWIW,与包装的结构相比,具有单个字段的结构 没有 运行时开销。
猜你喜欢
  • 2017-04-10
  • 2022-11-03
  • 1970-01-01
  • 2014-03-15
  • 2012-11-25
  • 2010-11-13
  • 2014-03-11
  • 2011-12-10
  • 1970-01-01
相关资源
最近更新 更多