3

私の質問は、オーダスキーの講義3.5についてです(課題ではありません!):

19:15の演習では、「タイプは何ですか:」と尋ねられますif (true) 1 else false

彼の説明の中で、オーダスキーは、タイプはと(2つの条件付きブランチのタイプ)AnyValの最も具体的なスーパータイプであるためであると主張しています。IntBoolean

タイプチェッカーが最初のブランチだけが実際に関連していることを確認するのに十分賢くないのはなぜかと自問しています。したがって、タイプは次のように推測できIntますか?

4

4 に答える 4

11

これは、以下がJavaでコンパイルされない理由と同様の質問です。

throw new Foo();
return 42;  //unreachable statement

しかし、これはコンパイルされます:

if(true)
  throw new Foo();
return 42;

基本的に、コンパイラはどこかで停止する必要があります。特にScalaコンパイラはすでにかなり遅いです。常に合格条件として認識されると、次のtrueように尋ねられる場合があります。1 == 12 * 21 == 42x == 7xval

線を引くのは難しいので、コンパイラはすべてifが両方のブランチを持つことができると単純に想定します。そのような不可能な、またはおそらく正しくない式を発見するのは、IDEまたはコード検証ツールの責任です。

于 2012-10-02T18:59:44.243 に答える
4

私はあなたが望まないだろうと主張しますInt-推論されたタイプは最適化に依存するべきではなく、むしろ開発者によって書かれたテキストに依存するべきです。そうしないと、何が得られるかを予測するのが難しくなります。この場合はそうではありませんが、ほとんどの場合よりも明らかに明白です。

于 2012-10-02T19:01:42.333 に答える
2

タイプチェッカーはプログラムの実行について何も想定していないためです。ifステートメントのどのブランチが実行されるかを予測しようとはしません。一般的なケースでは決定可能ではなく、この特定のケースは実際にはそのような予測を価値のあるものにするのに十分な頻度で発生することはありません。

このような予測を行うと、タイピングルールのロジックも複雑になります。ifステートメントのタイプがIntであり、ブランチの1つがIntのサブタイプではないタイプである場合、ブランチが実行されない場合でも、それは確かに人々の期待と矛盾します。型チェッカーが、実行されないことがわかっているブランチの型エラーについて文句を言わないのと同じように、誰もそれを望んでいません。

于 2012-10-02T19:04:45.020 に答える
0

trueチェーンの上の定義された場所に移動できるので、これは私に考えさせられました。ある時点で、コンパイラーは多くのパスをたどって、最良の推測を行う必要があります。

これは常に真実です

if (true) 1 else false

これもそうですが、より高いレベルで

val presetBoolean = true
if (presetBoolean) 1 else false

これもそうですが、評価された式を通して

val presetBoolean = (1 == 1)
if (presetBoolean) 1 else false

これも一定ですが、この場合は別のオブジェクトへの参照を渡します(そして私のプログラムの唯一のインスタンスです

case object CallWithPreset {
  def apply(presetBoolean:Boolean) {
    if(presetBoolean) 1 else false
  }
}

CallWithPreset(true)

推論ごとにコンパイル時間の形でオーバーヘッドがあります。ですから、些細なケースでは簡単かもしれないと思いますが、他のケースではおそらくそうではないでしょう。ただし、すべてではなく一部のケースを許可した場合、それぞれが異なる推論を行う可能性があり、混乱を招く可能性があります。

たとえば、これが機能した場合:

val myType:Int = if(true) 1 else false

しかし、これはコンパイルエラーを引き起こしました:

val presetBoolean = true
val myType:Int = if (presetBoolean) 1 else false
于 2012-10-02T19:47:33.513 に答える