簡體   English   中英

在Scala中,為什么我可以在這里使用`Unit`作為返回類型?

[英]In Scala, why can I use `Unit` as return type here?

代碼如下:

scala> def f(x:Int => Unit):Unit = 1
<console>:7: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
       def f(x:Int => Unit):Unit = 1
                                   ^
f: (x: Int => Unit)Unit

scala> f(_=>2);
<console>:9: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
              f(_=>2);
                   ^

scala> f(_=>List(1,2));

上面的所有三個表達式都在REPL中工作(有一些警告),但它們看起來有點令人困惑。

在第一個表達式中, f的返回類型是Unit ,它是AnyVal的子類型,但不是Int的超類型,因此,我無法理解為什么1可以用作返回值。

在第二個表達式中, _=>2也使用2而不是Unit作為返回值,它與定義沖突。

在第三個表達式中, _=> List(1,2)甚至使用ListAnyRef子類型作為返回值,但REPL仍然沒有抱怨這個..

有沒有人有關於為什么Unit可以容忍非子類型轉換的想法? 謝謝!

在這種情況下,Scala會自動插入() (單例Unit值)以使類型檢查工作。 所以你所擁有的相當於:

def f(x:Int => Unit):Unit = { 1; () }

這在Scala中被稱為“價值丟棄”。 規格

價值丟棄

如果e具有某種值類型且預期類型為Unit ,則通過將{ e; () }嵌入到術語{ e; () }來將e轉換為期望類型{ e; () } { e; () }

與許多編程語言一樣,這意味着只是“拋棄”表達式的返回值。 這允許您創建一個僅使用表達式副作用的Unit類型的方法。

檢查SLS中的隱式轉換部分

ValueDiscarding。 如果e具有某種值類型且預期類型為Unit,則通過將e嵌入到術語{e;中來將e轉換為期望類型。 ()}。

除了Ben Reich的答案:

從概念上講,在Scala中,類型Unit是每種其他類型的超類型。 因此,每個值(包括Int )都可以分配給Unit 實際上,如果用作方法的返回類型,編譯器將丟棄結果值,為方法提供JVM / Java void類型。

順便說一下, Nothing是完全相反的:從概念上講,它是所有其他類型的子類型。 由於不存在任何Nothing實例,因此任何其他類型的實例都不能與Nothing分配兼容。

Java的void某種程度上是兩者的不完全混合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM