Scala Language
유형 추론
수색…
지역 유형 유추
스칼라는 언어에 내장 된 강력한 유형 추론 메커니즘을 사용합니다. 이 메커니즘을 '로컬 형식 유추'라고합니다.
val i = 1 + 2 // the type of i is Int
val s = "I am a String" // the type of s is String
def squared(x : Int) = x*x // the return type of squared is Int
컴파일러는 초기화 표현식에서 변수 유형을 유추 할 수 있습니다. 마찬가지로 메소드의 리턴 유형은 메소드 본문에서 리턴 된 유형과 같기 때문에 생략 할 수 있습니다. 위의 예제는 명시 적 형식 선언과 같습니다.
val i: Int = 1 + 2
val s: String = "I am a String"
def squared(x : Int): Int = x*x
유형 유추 및 제네릭
스칼라 컴파일러는 다형 메소드가 호출되거나 일반 클래스가 인스턴스화 될 때 유형 매개 변수를 추론 할 수 있습니다.
case class InferedPair[A, B](a: A, b: B)
val pairFirstInst = InferedPair("Husband", "Wife") //type is InferedPair[String, String]
// Equivalent, with type explicitly defined
val pairSecondInst: InferedPair[String, String]
= InferedPair[String, String]("Husband", "Wife")
위 형식 유추 형식은 Java 7에서 소개 된 Diamond Operator 와 유사합니다.
추론의 한계
스칼라 유형 추론이 작동하지 않는 시나리오가 있습니다. 예를 들어, 컴파일러는 메소드 매개 변수의 유형을 추론 할 수 없습니다.
def add(a, b) = a + b // Does not compile
def add(a: Int, b: Int) = a + b // Compiles
def add(a: Int, b: Int): Int = a + b // Equivalent expression, compiles
컴파일러는 재귀 메서드의 반환 형식을 유추 할 수 없습니다.
// Does not compile
def factorial(n: Int) = if (n == 0 || n == 1) 1 else n * factorial(n - 1)
// Compiles
def factorial(n: Int): Int = if (n == 0 || n == 1) 1 else n * factorial(n - 1)
아무것도 유추하는 것을 막기.
이 블로그 게시물을 기반으로 합니다 .
다음과 같은 메소드가 있다고 가정 해보십시오.
def get[T]: Option[T] = ???
제네릭 매개 변수를 지정하지 않고 호출하려고하면 Nothing
유추되지 않습니다. 실제 구현에는 그리 유용하지 않습니다. 그 결과는 유용하지 않습니다. 다음 해결책을 사용하면 NotNothing
컨텍스트 바인딩으로 인해 예상되는 형식을 지정하지 않고 메서드를 사용할 수 있습니다 (이 예제에서는 RuntimeClass
도 Nothing
아닌 ClassTags
경우 제외되지만 RuntimeClass
는 유추됩니다).
@implicitNotFound("Nothing was inferred")
sealed trait NotNothing[-T]
object NotNothing {
implicit object notNothing extends NotNothing[Any]
//We do not want Nothing to be inferred, so make an ambigous implicit
implicit object `\n The error is because the type parameter was resolved to Nothing` extends NotNothing[Nothing]
//For classtags, RuntimeClass can also be inferred, so making that ambigous too
implicit object `\n The error is because the type parameter was resolved to RuntimeClass` extends NotNothing[RuntimeClass]
}
object ObjectStore {
//Using context bounds
def get[T: NotNothing]: Option[T] = {
???
}
def newArray[T](length: Int = 10)(implicit ct: ClassTag[T], evNotNothing: NotNothing[T]): Option[Array[T]] = ???
}
사용 예 :
object X {
//Fails to compile
//val nothingInferred = ObjectStore.get
val anOption = ObjectStore.get[String]
val optionalArray = ObjectStore.newArray[AnyRef]()
//Fails to compile
//val runtimeClassInferred = ObjectStore.newArray()
}
Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow