유쾌하게 간단한 방법을 사용해야하는 몇 가지 이유가 있습니다 implicitly
.
암시 적 뷰 이해 / 문제 해결
선택의 접두사를 고려할 때 암시 적 뷰가 트리거 될 수 있습니다 (예 : 고려할 수 the.prefix.selection(args)
있는 멤버 selection
가 포함되지 않은 경우 args
( args
암시 적 뷰로 변환 한 후에도 ))이 경우 컴파일러는 로컬로 정의 된 암시 적 멤버를 찾습니다. 현재 또는 둘러싸는 범위에서 상속되거나 가져온 범위에서 해당 유형의 함수에서 정의 된 the.prefix
유형 selection
또는 동등한 암시 적 메소드 가있는 유형의 함수입니다 .
scala> 1.min(2) // Int doesn't have min defined, where did that come from?
res21: Int = 1
scala> implicitly[Int => { def min(i: Int): Any }]
res22: (Int) => AnyRef{def min(i: Int): Any} = <function1>
scala> res22(1) //
res23: AnyRef{def min(i: Int): Int} = 1
scala> .getClass
res24: java.lang.Class[_] = class scala.runtime.RichInt
다음과 같이 표현식이 예상 유형을 준수하지 않는 경우 암시 적 뷰가 트리거 될 수도 있습니다.
scala> 1: scala.runtime.RichInt
res25: scala.runtime.RichInt = 1
컴파일러는이 함수를 찾습니다.
scala> implicitly[Int => scala.runtime.RichInt]
res26: (Int) => scala.runtime.RichInt = <function1>
컨텍스트 바운드에 의해 도입 된 암시 적 매개 변수 액세스
암시 적 매개 변수는 암시 적 뷰보다 스칼라의 더 중요한 기능 일 것입니다. 형식 클래스 패턴을 지원합니다. 표준 라이브러리는 이것을 몇 곳 scala.Ordering
에서 사용 SeqLike#sorted
합니다. 사용 방법을 참조하십시오 . 암시 적 매개 변수는 또한 배열 매니페스트 및 CanBuildFrom
인스턴스 를 전달하는 데 사용됩니다 .
스칼라 2.8에서는 컨텍스트 바인드라고하는 암시 적 매개 변수에 대한 간단한 구문을 사용할 수 있습니다. 간단히 말해서, type 매개 변수 A
를 갖는 메소드는 다음 유형 의 암시 적 매개 변수 를 필요로합니다 M[A]
.
def foo[A](implicit ma: M[A])
다음과 같이 다시 작성할 수 있습니다.
def foo[A: M]
그러나 암시 적 매개 변수를 전달하지만 이름을 지정하지 않는 요점은 무엇입니까? 메소드를 구현할 때 어떻게 유용 foo
합니까?
암시 적 매개 변수를 직접 참조 할 필요가없는 경우가 종종 있으며, 호출 된 다른 메소드에 대한 암시 적 인수로 터널링됩니다. 필요한 경우 컨텍스트 바인딩을 사용하여 간결한 메소드 서명을 유지 implicitly
하고 값을 구체화하기 위해 호출 할 수 있습니다.
def foo[A: M] = {
val ma = implicitly[M[A]]
}
암시 적 매개 변수의 서브 세트를 명시 적으로 전달
타입 클래스 기반 접근 방식을 사용하여 사람을 예쁘게 인쇄하는 메소드를 호출한다고 가정하십시오.
trait Show[T] { def show(t: T): String }
object Show {
implicit def IntShow: Show[Int] = new Show[Int] { def show(i: Int) = i.toString }
implicit def StringShow: Show[String] = new Show[String] { def show(s: String) = s }
def ShoutyStringShow: Show[String] = new Show[String] { def show(s: String) = s.toUpperCase }
}
case class Person(name: String, age: Int)
object Person {
implicit def PersonShow(implicit si: Show[Int], ss: Show[String]): Show[Person] = new Show[Person] {
def show(p: Person) = "Person(name=" + ss.show(p.name) + ", age=" + si.show(p.age) + ")"
}
}
val p = Person("bob", 25)
implicitly[Show[Person]].show(p)
이름이 출력되는 방식을 바꾸려면 어떻게해야합니까? 명시 적으로 호출 PersonShow
하고 대안을 명시 적으로 전달할 수 Show[String]
있지만 컴파일러가을 전달하기를 바랍니다 Show[Int]
.
Person.PersonShow(si = implicitly, ss = Show.ShoutyStringShow).show(p)