はのは少し違った視点からこのを見てみましょう参照してください、実際には、はパラメータは何ですか?どういう意味ですか?
まず、よく知っているものから始めましょう:値のパラメータ。サブルーチンの値パラメータはどういう意味ですか?それは意味
def foo(a, b) = { /* … */ } // deliberately ignoring types and the body
::私は2つのパラメータ、a
とb
でサブルーチンfoo
を持って、我々はこのような何かを持っている、と言います。そして、サブルーチンは一般です、の実際の具体的な値はa
とb
です。 すべての値がa
とb
の場合は、がありません。の値はa
とb
の値であるためです。
もう少し具体的な:
def plus(a: Int, b: Int) = a + b
ここでも、plus
はa
とb
の実際の値が何であるかを知りません。 2
と3
だけでなく、23
と42
または0
と0
の場合も同様です。 a
とb
の具体的な値は完全に完全に知られていません。 a
とb
が存在することだけがわかります。
ここで、タイプのパラメータは、値レベルではなくタイプレベルでのみ同じです。 「私はものを持って、私はそれが何であるか見当がつかない(と私は気にしない)が、私は電話するよ:
blabla[A]
はblabla(a)
が値レベルでの手段として、タイプレベルで同じことを意味し、それはA
です。
あなたが効果的に行ったことは、A
について何も知らないことをScalaに伝えることです。しかし、あなたはそれを使って(あるいはそのインスタンスを使って)何かを行います:それを追加します。しかし、どのようにあなたもあなたを知っています缶それを追加しますか?あなたはそれが何であるかを知りません!
ので、はおそらく動作しないすることができ、それを追加し、それがは失敗しなければなりません!
ただし、の方法はです。これは、少し不思議で、scala.Predef
オブジェクトの定義済みの暗黙的な変換のいくつかと関係があります。特に、there is an implicit conversion for string concatenation, which can convert an arbitrary object into a String
and then concatenate another String
to it。この場合、a
をany2stringadd
に変換してからb
を追加しようとしますが、メソッドはString
を引数にとり、String
が必要であるという奇妙なエラーメッセージが表示されます。あなたは、複雑な型エラーがある場合
は、時々ポップアップ表示の他の同様のタイプのカップルがあります。
Any
、AnyRef
、AnyVal
:これらのタイプは、Scalaの型階層の最上部に座っています。ときどき、2つの異なるコードパスから同じ型を返すと思われるプログラミングエラーがありますが、実際には2つの異なる型を返す場合、Scalaはそれにもかかわらず両方の共通型を推測しようとします。共通祖先はAny
,AnyRef
またはAnyVal
です。 (これはJavaやC#でObject
のようなものです)
Serializable
:これは実際には上記と同じです。完全に異なる型の多くはSerializable
インターフェイスを実装しているので、実際に同じ型を期待する2つの型が非常に異なる場合、ScalaはSerializable
を最も近い共通の祖先として推測し、Serializable
それはサポートしていません。
Product
は(Tuple22
すなわちTuple1
、Tuple2
、...)(...、即ちProduct1
、Product2
Product22
)全てProduct
Sのスーパー形質であり、従って全てTuple
S。 Product
もすべてcase class
に混在しています。 Option
とあなたのcase class Foo
Product
かと推測される間、その後、最も正確な一般的なタイプを使用すると、異なるアリティの2 Tuple
秒または2個の無関係なcase class
ESを持っているのであれば、(例えば、あなたは時々None
を返すが、その後偶然代わりSome(somethingOfTypeFoo)
のsomethingOfTypeFoo
を返します)...
Product with Serializable
:上記の組み合わせを受け取ることもできます。例えば。 Tuple
がSerializable
であるので、このは実際には異なるアリティの2つの最も正確な一般的なタイプです。これらの問題に実行する
一般的な方法の1つは、else
なしの条件式である:
if (true) 42
このリターンを何種類? Int
?いいえ! then
ブランチはInt
を返しますが、else
ブランチはを返しません。(else
ブランチがないため)。スカラは実際に何も返さない戻り値の型を持っています:Unit
。 Unit
はAnyVal
のサブタイプであり、Int
はAnyVal
のサブタイプであるため、条件式の2つのブランチのタイプのうち最も近い共通祖先は、ではありません。Int
ではありません。 (注:else
ブランチが到達不能であるという事実は、入力の観点からは無関係です。到達可能性は実行時のものです。タイプはコンパイル時のものです)