2017-08-03 17 views
6

Scalaでは、変数の宣言があるとします。リテラルや変数をCharに代入するときのスカラの振る舞い

var x: Char = 'a' 

次に、この文字に1を追加して更新してください。

x = x + 1 

コンパイルエラーが発生しました。タイプミスマッチが見つかりました。必要な文字です。しかし、私はコンパイルエラーなしでこれを行うことができます。

x = 'a' + 1 

私はしかし、私は正確な動作のまわりで私の頭を取得しようとしている、これはオブジェクト対リテラル値とは何かを持って推測しています。 Charにリテラルな整数を明示的に割り当てることができます。 97となり、97-32の結果を割り当てることもできます。しかし、私が97-32 + 5と言うと、型の不一致エラーが発生します。どの時点で、コンパイラは、リテラルを結果とする式とオブジェクトを結果とする式を区別しますか?

答えて

1

割り当てがキーです。以下のREPLセッションで 見て:あなたはすべてがうまく行く変数の値を再割り当てしようとしない限り、あなたが見ることができます

[email protected] ~ $ scala 
Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_131). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> val x:Char = 'a' 
x: Char = a 

scala> x + 1 
res0: Int = 98 

scala> var y:Char = 'a' 
y: Char = a 

scala> y + 1 
res1: Int = 98 

scala> y = y + 1 
<console>:8: error: type mismatch; 
found : Int 
required: Char 
     y = y + 1 
      ^

scala> 

ように。 'a'+1またはx + 1と書くと、Intに変換されます。 最終的にx = x + 1に再割り当てしようとすると、Intの値をChar変数に割り当てようとしています。コンパイルエラーが発生する理由を説明します。

Charコンパニオンオブジェクトには、implicit def char2int(x: Char): Intメソッドがあります。 私はvar x:Char = 'a' + 1で最初に起こるのは、このメソッドを呼び出すことで、 'a'を97に変換すると考えられます。次に97に1が追加され、両方ともIntとなります。次に、変数xval y:Char = 98と同じ方法でインスタンス化されます。これは、変数の初期化の仕組みを説明していると思います。

+1

この答えていませんが、なぜ 'のvar X:シャア= A + 1点の '作品が、' X = X + 1 'はしません。最初の代入では、 'a + 1'は暗黙的に' Char'に変換されますが、再割り当てではそれはしません。どうして? –

+0

私は自分の答えを編集しました。これが私の考えとは違う場合は、回答の削除に投票してください。その理由は、根本的なものを理解できないからです。 –

+0

また、「最初の割り当て」と「初期化」を区別しましょう。これは重要だと思います。変数の初期化は値の初期化と変わりません。私は 'val x:Char = 'a' + 1'は' var x:Char = 'a' + 1'と同じです。 –

1

リテラルを入力する特別なルールがありますin the spec。あなたが書くことができます

However, if the expected type pt of a literal in an expression is either Byte, Short, or Char and the integer number fits in the numeric range defined by the type, then the number is converted to type pt and the literal's type is pt.

scala> 97 : Char 
res0: Char = a 

scala> 97 + 1 : Char 
res1: Char = b 

こそこそ、彼らはここで定数式を意味します。しかし、定数式のdefinitionはプラットフォーム固有のものであるため、技術的にはres1が定数フォールドされていないとコンパイルに失敗する可能性があります。

関連する質問についてconstant folding in scaladocがscaladoc下型チェックの奇妙な損失を示しています。

$ ~/scala-2.12.3/bin/scaladoc -d /tmp folded.scala 
folded.scala:9: error: type mismatch; 
found : Int 
required: Char 
    x = 'a' - 32 + 5 
       ^
model contains 4 documentable templates 
one error found 
+0

仕様からのそのパラグラフの私の解釈が正しい場合、 'a' + 1は整数リテラル(98)を結果として得なければなりません。これは正当にChar型の変数に代入されます。そのタイプ? x + 1はリテラルにならないので、このルールは適用されません。これは正しいです? – Tranquility

+0

はい、 'x + 1'は定数式またはリテラルではなく、' x'はランタイム値です。 'x + y + z'は定数が折り返されたリテラル(値が定数の場合)でなければならないことは私には分かりません。 scaladocの動作はバグか実装の成果物ですか? scalacでは、あなたは一定の折り畳みを得る。誰もdocをもう書いていないので、scaladocは問題ではありません。 –

関連する問題