11

typeキーワードと#演算子がscalaでどのように機能し、どのように使用するかを誰かが説明できますか? 例を見てください。

//Example1
scala>  type t1 = Option.type
defined type alias t1

//Shouldn't this work since previous example simply works?
scala>  type t2 = String.type
<console>:7: error: type mismatch;
 found   : String.type
 required: AnyRef
       type t2 = String.type
         ^

//lets define custom trait T
scala>  trait T
defined trait T

//... and obtain it's type like in Example1.
//Shouldn't this work since previous Example1 simply works?
scala>  type t3 = T.type
<console>:7: error: not found: value T
       type t3 = T.type
         ^

//Lets define some value of type T
scala>  val v4 = new T{}
v4: T = $anon$1@5c3e8c76

//and obtain it's type (works)
scala>  type t4 = v4.type
defined type alias t4

//this doesn't work
scala>  type t4_1 = (new T{}).type
<console>:1: error: identifier expected but 'new' found.
       type t4_1 = (new T{}).type

//as well as this (doesn't work)
scala>  type t5 = "abc".type
<console>:1: error: identifier expected but string literal found.
       type t5 = "abc".type
         ^

//but this compiles well
scala>  val v6 = "abc"
v6: String = abc

scala>  type t6 = v6.type
defined type alias t6


//lets create some values of created types:
scala>  type t1 = Option.type
defined type alias t1

scala>  val v1_1 = Some(10)
v1_1: Some[Int] = Some(10)

scala>  type t7 = v1_1.type
defined type alias t7

scala>  val v7:t7 = null
v7: t7 = null

scala>  val v7_1:t7 = v1_1
v7_1: t7 = Some(10)

scala>  val v7_2:t7 = Some(10)
<console>:9: error: type mismatch;
 found   : Some[Int]
 required: t7
    (which expands to)  v1_1.type
       val v7_2:t7 = Some(10)
             ^


//next let's try # operator

scala>  class X[A,B](a:A,b:B)
defined class X

//doesn't work
scala>  type xa = X[A,B]#A
<console>:8: error: not found: type A
       type xa = X[A,B]#A
           ^
<console>:8: error: not found: type B
       type xa = X[A,B]#A
             ^

//but such approach works:
scala>  trait X2[C]{
  type A
  type B
  val c:C
}
defined trait X2

scala>  type xa2_1 = X2[String]#A
defined type alias xa2_1

scala>  type xa2_2[M] = X2[M]#A
defined type alias xa2_2
4

2 に答える 2

14

まず、 についての質問type:

型宣言の右側は、安定したパスを持つ型の名前でなければなりません。だからあなたの例を一つずつ取ってください:

type t1 = Option.type

t1 は、クラスではなく、Option オブジェクトのタイプのエイリアスです。Option

type t2 = String.type

Stringオブジェクトがないため、これはエラーです。String は Java クラスであり、さまざまな規則の下で動作するため (Java クラスにはコンパニオンがないため)、このエラーは少し奇妙です。

type t3 = T.type

同上。T は Scala クラスであり、コンパイラは「T はオブジェクトに型を指定していません」と明確に言うことができるため、今回はエラーがより明確になります。

type t4 = v4.type

これは、 val で指定されたオブジェクトのシングルトン タイプですv4。型 T のインスタンスも、式によって作成された匿名クラスのインスタンスも参照しませんnew T{}。とのみで表されるタイプを参照します。つまり、それらはそのタイプの唯一の許可された値です。v4null

type t4_1 = (new T{}).type

タイプを取得しているものは安定した識別子でなければならないため、これは違法です(大まかに言えば、参照元が決して変更できない識別子-識別子へのフルパスがパッケージ、objects、およびvalsの名前のみで構成されている場合) 、安定しています)。

type t5 = "abc".type

同上。

type t6 = v6.type

v6安定した識別子です。 名前(および)t6で参照される String の特定のインスタンスのみが存在する型です。v6null

type v6 = v1_1.type

繰り返しますが、シングルトン型です。

val v7: t7 = null

nullタイプの有効な値ですt7

val v7_1:t7 = v1_1

この特定のオブジェクトも同様です。

val v7_2:t7 = Some(10)

しかし、これはのオブジェクトであり (to であっても、==tov7eqはありません)、したがって、この型のメンバーではありません。

今について#

class X[A,B](a:A,b:B)

AおよびBは型パラメーターです。クラス外から参照することはできません。private[this]正確ではありませんが、これらは可視性のある抽象型エイリアスのように考えることができます。

type xa = X[A,B]#A

ええ、見えません。

type xa2_1 = X2[String]#A

これ Apublic 型エイリアスを参照するため、クラス外で名前で参照できます。このタイプについてまったく何も知らないので、この特定のケースはまったく役に立たないことに注意してください。特性X2に type の値を返すメソッドがある場合、次のAようなことができます

val aFromX2: xa2_1 = x2instance.methodThatReturnsAnA

..しかし、2 つの s が同じ型を参照するX2[String]という保証がないため、それを のインスタンスに戻すことさえできませんでした。A一方、具体的なインスタンスがある場合は、次のようにすることができます。

def passAroundA(x2instance: X2[String]) {
  type x2a = x2instance.A // note dot, not #
  val a: x2a = x2instance.methodThatReturnsAnA
  x2instance.methodThatTakesAnA(a)
}

この場合、A実際に何が何であるかはわかりませんが、2 つのメソッドが同じ型 (x2instanceの構成で修正されたもの) を使用していることがわかっているため、機能します。

于 2012-10-18T17:03:52.747 に答える