71

どちらのタイプも、何も返さない関数を示しますUnitNothingそれらの違いは何ですか?

4

4 に答える 4

95

Unitは、値が1つだけのタイプです。「ユニットタイプ」を参照してください。一方、可能なNothingはありません-ボトムタイプを参照してください。

何も返さない関数は、returntypeを持っている必要がありUnitます。その場合Nothing、関数は結果を返すことができませんでした。関数を終了する唯一の方法は、例外によるものです。


Nothing別の方法で使用されます。それは2つの特性によって特徴付けられます:

  1. Nothing他のすべてのタイプ(を含むNull)のサブタイプです。
  2. このタイプのインスタンスは存在しません。

これはいつ役に立ちますか?考えてみてくださいNone

object None extends Option[Nothing]

Optionはその型パラメーターで共変でありNothing、すべてOption[Nothing]のサブタイプであるため、はすべてのタイプのサブOption[A]タイプAです。したがって、すべてNoneののサブタイプである1つのオブジェクトを作成できます。インスタンス化できないため、これは合理的であり、常に値がありません。同様にOption[A]ANothingOption[Nothing]

object Nil extends List[Nothing]

Unit論理的真理に対応し、カリー・ハワード同形性Nothingの下で論理的真理に対応します。ここでは、型を命題と見なし、関数を証明と見なします。

于 2012-11-24T09:13:36.113 に答える
23

Unitつまり、(a)関数には入力や出力などの副作用があり、(b)これらの副作用が関数の主な目的です。もちろん、関数のタイプが。と異なっていても、関数には副作用がありますUnit

NothingはScalaの特殊な型です。これは、(a)値がない(Unitには値が1つだけある- ())ため、型の値を返すことができないためNothing、(b)他のすべての型のサブタイプであるためです。つまり、何かがタイプNothingを持っている場合、他のタイプの代わりに(サブタイピングを介して)使用できますが、結果は生成されません。これは、例外を処理するのに役立ちますthrow。式のタイプはNothing、であるため、プログラムのどこでも使用できます。

簡単に言うNothingと、プログラムのエラーまたは終了があり、何も返されないことをUnit意味し、副作用があったことを意味しますが、実行は正常に終了し、結果はありません。

Scalaでのプログラミングには、その良い説明があります。

于 2012-11-24T09:22:48.113 に答える
7

Petrの応答に1つの側面を追加するには、次Nothingのようにします。タイプ階層で重要な役割を果たします。ボトムタイプです。これは、他のすべてのタイプのサブタイプであることを意味します。これは、すべてのスーパータイプであるの反対のようなAnyものです。あなたはここで素晴らしい説明を見つけることができます。

于 2012-11-24T09:22:56.840 に答える
1

単位

単位はJavaの無効と同じです。javaのvoidはキーワードですが、UnitはKotlinのオブジェクトです。

これで、関数がKotlinでUnitを返す場合、それは意味のあるものを何も返さないことを意味します。その関数は一連のコードを実行し、実行フローを返します。

何もない

まったく別の種類のものはありません。Javaでは何とも関連付けることができません。JavaにはNothingのようなものはありません。

実行の終了を意味するものはありません。関数がNothingを返す場合、文字通り何も返さないことを意味します。実行フローすらありません。

ブラックホールのようなものはなく、入ってくるものは出てこない、光さえも出てこない(ここでは光は「実行の流れ」である)。ユニットの場合、最も少ない光が出ます。

したがって、関数がNothingを返す場合、コードのフローはそこで終了し、その後に書き込まれるものはすべて到達不能になります。

次のコードを参照してください。

fun main() {
    unitFun()
    println("after unit")
    nothingFun()
    println("after nothing")   //you get warning here saying "unreachable code"
}

fun nothingFun(): Nothing {
    println("inside nothing")
    throw Exception()
}

fun unitFun(): Unit {
    println("inside unit")
}

出力は

inside unit
after unit
inside nothing
Exception in thread "main" java.lang.Exception

注:書くとすぐに警告が表示されます

println("after nothing")     UnReachable Code

そして、あなたはその理由を知っています、それはnothingFunが実行フローを送り返さないからです。

ここでこれを完了するもう1つのことは、Nothingを返す関数は、いかなる種類の例外もスローする必要がないということです。

理由:一般的なステートメントを記述した場合(例外をスローしない場合)、関数は戻り型に一致し、Nothingを返すものはありません。つまり、実行フローを吸い込み、決して返さないものはありません。戻る。すべてが何かを返します、ユニットでさえ何かです。

これで、クラスは何もないと言えるので、オブジェクトを作成してそれ自体を返すことができます。Nohhhhhhh?大きなnohhhh?

コンストラクターが1つあるクラスはありませんが、プライベートであるため、そのオブジェクトを作成することもできません。

最後のビット

舞台裏では、ユニットは逆コンパイルされたバイトコードでvoid(small v)に変換されますが、NothingはVoid(capital V)に変換されます。

以下のコードを参照してください。

var user = null               //First
var user : User? =null        //Second

ここで、2番目のステートメントは、Nullable-Userタイプのユーザーを示しています。最初のステートメントのユーザーのタイプは何ですか?

何か推測?

Nullable-Nothingタイプです。

最初のステートメントを次のように見てみてください

var user : Nothing? = null

今、ボンネットの下で何が起こっているのか、

Void user = (Void)null;              //First
User user = (User)null;        //Second
于 2019-08-12T12:46:15.937 に答える