Scala에서 유형 지정의 목적은 무엇입니까?
사양에 어떤 유형 지정이 있는지에 대한 정보가 많지 않으며 그 목적에 대한 내용도 확실히 없습니다. "전달하는 varargs 작동하기"외에 어떤 용도로 유형 지정을 사용합니까? 다음은 구문 및 사용 효과에 대한 몇 가지 스칼라 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
유형 지정은 가능한 모든 유효한 유형에서 표현식에서 예상하는 유형을 컴파일러에 알려주는 것입니다.
유형은 분산 및 유형 선언과 같은 기존 제약 조건을 준수하고 " is a "에 적용되는 표현식 유형 중 하나 이거나 범위에 적용되는 변환 이있는 경우 유효합니다 .
따라서, java.lang.String extends java.lang.Object
any String
도 Object
. 귀하의 예제에서 당신은 당신이 표현이 원하는 선언 s
로 취급 Object
하는 없습니다 String
. 거기를 방해하는 제약 조건입니다 원하는 유형이 유형 중 하나이기 때문에 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)
또한 타입 ascripting하여이 문제를 해결 한 수 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 사양 (2009 년 3 월 15 일 초안)이 유형 지정에 대해 말한 내용입니다.
Expr1 ::= ...
| PostfixExpr Ascription
Ascription ::= ‘:’ InfixType
| ‘:’ Annotation {Annotation}
| ‘:’ ‘_’ ‘*’
한 가지 가능성은 네트워크 및 직렬 프로토콜 수준의 경우 다음과 같습니다.
val x = 2 : Byte
보다 훨씬 깨끗하다
val x = 2.asInstanceOf[Byte]
두 번째 형식은 런타임 변환 (컴파일러에서 처리하지 않음)이며 흥미로운 오버 / 언더 플로 조건으로 이어질 수 있습니다.
I use type ascription to paper over holes in Scala's type inference. For example, foldLeft over a collection of type A takes an initial element of type B and a function (B, A) => B that is used to fold the elements of the collection into the initial element. The actual value of type B is inferred from the type of the initial element. Since Nil extends List[Nothing], using it as an initial element causes problems:
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)
Alternatively, you could just use List.empty[Int] instead of Nil:List[Int].
scala> x.foldLeft(List.empty[Int])( (acc,elem) => elem::acc )
res3: List[Int] = List(4, 3, 2, 1)
edit: List.empty[A] is implemented as
override def empty[A]: List[A] = Nil
This is effectively a more verbose form of Nil:List[A]
You may find this thread illuminating, if a bit convoluted to follow. The important thing to note is that you're adding constraint hints to the type checker - it gives you a little more control over what that compilation phase is doing.
Type Inference: We can skip Explicitly giving Name of Type of Something in source code, called Type Inference.(Although required in some exceptional cases.)
Type Ascription: Being explicit about the type of something is called a Type Ascription. What Difference It can make?
ex: val x = 2 : Byte
also see: 1. We can explicitly give return type to our functions
def t1 : Option[Option[String]] = Some(None)
> t1: Option[Option[String]]
Another way of declaring this could be:
def t2 = Some(None: Option[String])
> t2: Some[Option[String]]
Here we did not give Option[Option[String]]
return type explicitly and Compiler inferred it as Some[Option[String]]
. Why Some[Option[String]]
is because we used type ascription in the definition.
Another way we can use the same definition is:
def t3 = Some(None)
> t3: Some[None.type]
This time We did not explicitly tell the compiler anything(neither this defi). And It inferred our definition as Some[None.type]
참고URL : https://stackoverflow.com/questions/2087250/what-is-the-purpose-of-type-ascriptions-in-scala
'program story' 카테고리의 다른 글
ASP.NET Core (.NET Core)와 ASP.NET Core (.NET Framework)의 차이점 (0) | 2020.10.30 |
---|---|
jQuery 표시 / 숨기기가 visible : hidden 대신 display : none을 사용하는 이유는 무엇입니까? (0) | 2020.10.30 |
Amazon S3 boto : 버킷에있는 파일의 이름을 어떻게 바꾸나요? (0) | 2020.10.30 |
여러 파일 유형을 검색하는 Unix find 명령에 해당하는 Windows (0) | 2020.10.30 |
범용 앱에서 iPad 및 iPhone Retina 그래픽을 모두 지원하는 방법 (0) | 2020.10.29 |