Scalaのタイプのアストリックの目的は何ですか?
-
21-09-2019 - |
質問
仕様には、どのような型の文字が何であるかについての情報にはあまり情報がありません。また、その目的については何もありません。 「パスバルルグを動作させる」以外に、タイプの文書を何に使用しますか?以下は、それを使用する構文と効果のためのいくつかのScala Replです。
scala> val s = "Dave"
s: java.lang.String = Dave
scala> val p = s:Object
p: java.lang.Object = Dave
scala> p.length
<console>:7: error: value length is not a member of java.lang.Object
p.length
^
scala> p.getClass
res10: java.lang.Class[_ <: java.lang.Object] = class java.lang.String
scala> s.getClass
res11: java.lang.Class[_ <: java.lang.Object] = class java.lang.String
scala> p.asInstanceOf[String].length
res9: Int = 4
解決
タイプの文字は、すべての可能な有効なタイプから、表現からどのタイプを期待するかをコンパイラに伝えるだけです。
タイプは、分散やタイプ宣言などの既存の制約を尊重する場合に有効であり、適用される式の型のいずれかのいずれかです。aです「または、範囲に適用される変換があります。
そう、 java.lang.String extends java.lang.Object
, したがって、いずれか String
またです Object
. 。あなたの例では、あなたはあなたが表現を望むことを宣言しました s
として扱われる Object
, 、ではありません String
. 。それを妨げる制約がなく、目的のタイプはタイプの1つであるため s
aです, 、 できます。
さて、なぜあなたはそれが欲しいのですか?このことを考慮:
scala> val s = "Dave"
s: java.lang.String = Dave
scala> val p = s: Object
p: java.lang.Object = Dave
scala> val ss = scala.collection.mutable.Set(s)
ss: scala.collection.mutable.Set[java.lang.String] = Set(Dave)
scala> val ps = scala.collection.mutable.Set(p)
ps: scala.collection.mutable.Set[java.lang.Object] = Set(Dave)
scala> ss += Nil
<console>:7: error: type mismatch;
found : scala.collection.immutable.Nil.type (with underlying type object Nil)
required: java.lang.String
ss += Nil
^
scala> ps += Nil
res3: ps.type = Set(List(), Dave)
また、タイプアスリップティングでこれを修正することもできます s
で ss
宣言、または宣言することもできます ss
'のタイプになります Set[AnyRef]
.
ただし、タイプ宣言は、識別子に値を割り当てている限り、同じことを達成します。もちろん、これがいつでもできることは、ワンショット識別子をコードに散らばることを気にしない場合です。たとえば、以下はコンパイルしません。
def prefixesOf(s: String) = s.foldLeft(Nil) {
case (head :: tail, char) => (head + char) :: head :: tail
case (lst, char) => char.toString :: lst
}
しかし、これは次のとおりです。
def prefixesOf(s: String) = s.foldLeft(Nil: List[String]) {
case (head :: tail, char) => (head + char) :: head :: tail
case (lst, char) => char.toString :: lst
}
ここで識別子を使用するのはばかげているでしょう Nil
. 。そして、私はただ書くことができましたが List[String]()
代わりに、それは常にオプションではありません。たとえば、これを考えてみてください。
def firstVowel(s: String) = s.foldLeft(None: Option[Char]) {
case (None, char) => if ("aeiou" contains char.toLower) Some(char) else None
case (vowel, _) => vowel
}
参照のために、これはScala 2.7 Spec(2009年3月15日ドラフト)がタイプの説明について言わなければならないことです。
Expr1 ::= ...
| PostfixExpr Ascription
Ascription ::= ‘:’ InfixType
| ‘:’ Annotation {Annotation}
| ‘:’ ‘_’ ‘*’
他のヒント
1つの可能性は、ネットワークおよびシリアルプロトコルレベルのものの場合です。
val x = 2 : Byte
よりクリーンです
val x = 2.asInstanceOf[Byte]
2番目のフォームは、ランタイムコンバージョン(コンパイラによって処理されない)であり、興味深いオーバー/アンダーフロー条件につながる可能性があります。
Scalaのタイプの推論の穴の上の紙にタイプの帰属を使用します。たとえば、タイプAのコレクション上の折り畳みめっきは、タイプBの初期要素とa関数(b、a)=> bを使用します。これは、コレクションの要素を初期要素に折り畳むために使用されます。タイプBの実際の値は、初期要素のタイプから推測されます。 nilはリスト[何もない]を拡張するため、それを初期要素として使用すると問題が発生します。
scala> val x = List(1,2,3,4)
x: List[Int] = List(1, 2, 3, 4)
scala> x.foldLeft(Nil)( (acc,elem) => elem::acc)
<console>:9: error: type mismatch;
found : List[Int]
required: scala.collection.immutable.Nil.type
x.foldLeft(Nil)( (acc,elem) => elem::acc)
^
scala> x.foldLeft(Nil:List[Int])( (acc,elem) => elem::acc )
res2: List[Int] = List(4, 3, 2, 1)
または、nil:list [int]の代わりにlist.empty [int]を使用することもできます。
scala> x.foldLeft(List.empty[Int])( (acc,elem) => elem::acc )
res3: List[Int] = List(4, 3, 2, 1)
編集:list.Empty [a]が実装されています
override def empty[A]: List[A] = Nil
これは事実上、nilのより冗長な形です:リスト[a
あなたは見つけるかもしれません このスレッド 照らされます。注意すべき重要なことは、タイプチェッカーに制約のヒントを追加することです。それは、そのコンパイルフェーズが何をしているかをもう少し制御できることです。
タイプ推論:型推論と呼ばれるソースコードのタイプの名前を明示的にスキップすることができます(いくつかの例外的なケースでは必要ですが)。
タイプの文字:何かのタイプについて明示的であることは、タイプの文書と呼ばれます。それはどのような違いを生むことができますか?
例:val x = 2:byte
参照:1。関数に明示的に返品タイプを与えることができます
def t1 : Option[Option[String]] = Some(None)
> t1: Option[Option[String]]
これを宣言する別の方法は次のとおりです。
def t2 = Some(None: Option[String])
> t2: Some[Option[String]]
ここで私たちは与えませんでした Option[Option[String]]
明示的に戻り、コンパイラはそれを推測しました Some[Option[String]]
。どうして Some[Option[String]]
定義でタイプの帰属を使用したためです。
同じ定義を使用できる別の方法は、次のとおりです。
def t3 = Some(None)
> t3: Some[None.type]
今回は、コンパイラに何も明示的に伝えませんでした(この義務も)。そして、それは私たちの定義をいくつかの[NONE.TYPE]として推測しました