【问题标题】:What is the Unit Type Behavior in Scala什么是 Scala 中的单元类型行为
【发布时间】:2021-02-21 08:22:02
【问题描述】:

为什么这段代码有效:

val f: String => Unit = {(_:String) => 2}

//or more succinctly

val f: String => Unit = _ => 2

显然我的函数体返回一个 int。但是预期的类型是 Unit

如果我这样做了

implicitly[String <:< Unit]

//Cannot prove that String <:< Unit.

因此,我对演员阵容是如何发生的有点困惑?为什么一开始就允许这样做

【问题讨论】:

  • 你的函数不返回 Int,编译器会处理它
  • 我的函数不返回 Int 是什么意思?显然,我的功能主体确实如此。这里有一个无法解释的打字,我想理解。
  • 基本上编译器会像这样重写你的代码_ =&gt; { 2; () }这被称为值丢弃,在规范中指定,如果你不喜欢它可以禁用它(对于纯 FP 代码这是一场噩梦,但对于命令式代码这非常有用)
  • 如何禁用它?有什么办法,没找到....
  • @MaatDeamon 也许是-Wvalue-discard/-Ywarn-value-discard-Xfatal-warningsdocs.scala-lang.org/overviews/compiler-options/index.html

标签: scala types


【解决方案1】:

在 Scala 中,任何类型 A 都可以转换为类型 Unit。它不是子类型化,它正在转换。 like type A 表示一些可能的副作用加上返回AUnit 表示我们忽略返回值但保留副作用。

【讨论】:

    【解决方案2】:

    这称为 Value Discarding,请参阅 Scala 语言规范的 6.26.1 Value Conversions, sub-section Value Discarding

    如果 ? 有某个值类型并且预期类型是 Unit,则 ? 通过将其嵌入术语 { ?; () } 中转换为预期类型。

    换句话说,您的代码被编译就像你写的

    val f: String => Unit = {(_:String) => { 2; () }}
    
    //or more succinctly
    
    val f: String => Unit = _ => { 2; () }
    

    我猜这个特性背后的意图是让来自命令式编程语言的程序员熟悉,在这种语言中,通常可以丢弃值。

    例如在C中,写是合法的

    printf("Hello");
    

    并丢弃返回值,即使printf 返回int。这与许多命令式编程语言所具有的 表达式语句语句表达式 的概念相吻合。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-08
      • 1970-01-01
      • 1970-01-01
      • 2018-09-28
      • 2012-02-01
      • 2011-03-05
      • 2014-09-10
      相关资源
      最近更新 更多