Scala에서 암시 적을 어떻게 연결할 수 있습니까?
pimp-my-library 패턴을 사용하면 해당 클래스에서 메서드를 구현하는 클래스로의 암시 적 변환을 사용할 수 있도록하여 클래스에 메서드를 추가 할 수 있습니다.
스칼라 내가에서 가져온 할 수 있도록이 같은 암시 적 변환은, 그러나, 일어나고 허용하지 않습니다 A
에 대한 C
암시 적 사용 A
에 대한 B
또 다른 암시 B
로를 C
. 이 제한을 피할 방법이 있습니까?
Scala는 메서드를 추가하기위한 자동 변환에 제한이 있습니다. 즉, 메서드를 찾으려고 할 때 하나 이상의 변환을 적용하지 않습니다. 예를 들면 :
class A(val n: Int)
class B(val m: Int, val n: Int)
class C(val m: Int, val n: Int, val o: Int) {
def total = m + n + o
}
// This demonstrates implicit conversion chaining restrictions
object T1 { // to make it easy to test on REPL
implicit def toA(n: Int): A = new A(n)
implicit def aToB(a: A): B = new B(a.n, a.n)
implicit def bToC(b: B): C = new C(b.m, b.n, b.m + b.n)
// won't work
println(5.total)
println(new A(5).total)
// works
println(new B(5, 5).total)
println(new C(5, 5, 10).total)
}
편집 :보기 경계 ( '<%')는 Scala 2.11 https://issues.scala-lang.org/browse/SI-7629 이후로 사용되지 않습니다 (대신 유형 클래스를 사용할 수 있음).
그러나 암시 적 정의에 암시 적 매개 변수 자체 (View bound)가 필요한 경우 Scala 는 필요한만큼 추가 암시 적 값을 찾습니다. 마지막 예에서 계속 :
// def m[A <% B](m: A) is the same thing as
// def m[A](m: A)(implicit ev: A => B)
object T2 {
implicit def toA(n: Int): A = new A(n)
implicit def aToB[A1 <% A](a: A1): B = new B(a.n, a.n)
implicit def bToC[B1 <% B](b: B1): C = new C(b.m, b.n, b.m + b.n)
// works
println(5.total)
println(new A(5).total)
println(new B(5, 5).total)
println(new C(5, 5, 10).total)
}
"마법!"이라고 말할 수도 있습니다. 별로. 컴파일러가 각각을 번역하는 방법은 다음과 같습니다.
object T1Translated {
implicit def toA(n: Int): A = new A(n)
implicit def aToB(a: A): B = new B(a.n, a.n)
implicit def bToC(b: B): C = new C(b.m, b.n, b.m + b.n)
// Scala won't do this
println(bToC(aToB(toA(5))).total)
println(bToC(aToB(new A(5))).total)
// Just this
println(bToC(new B(5, 5)).total)
// No implicits required
println(new C(5, 5, 10).total)
}
object T2Translated {
implicit def toA(n: Int): A = new A(n)
implicit def aToB[A1 <% A](a: A1): B = new B(a.n, a.n)
implicit def bToC[B1 <% B](b: B1): C = new C(b.m, b.n, b.m + b.n)
// Scala does this
println(bToC(5)(x => aToB(x)(y => toA(y))).total)
println(bToC(new A(5))(x => aToB(x)(identity)).total)
println(bToC(new B(5, 5))(identity).total)
// no implicits required
println(new C(5, 5, 10).total)
}
그래서, 동안은 bToC
암시 적 변환으로 사용되는, aToB
및 toA
로 전달되는 암시 적 매개 변수 대신 암시 적 변환으로 체인 연결되는.
편집하다
관심 관련 질문 :
암시 적 매개 변수를 사용하여 원을 만들 수도 있습니다. 그러나 다음과 같이 컴파일러에 의해 감지됩니다.
class Wrap {
class A(implicit b : B)
class B(implicit c : C)
class C(implicit a : A)
implicit def c = new C
implicit def b = new B
implicit def a = new A
}
The error(s) given to the user are not as clear as they could be, though; it just complains could not find implicit value for parameter
for all three construction site. That might obscure the underlying problem in less obvious cases.
Here's a code that also accumulates the path.
import scala.language.implicitConversions
// Vertices
case class A(l: List[Char])
case class B(l: List[Char])
case class C(l: List[Char])
case class D(l: List[Char])
case class E(l: List[Char])
// Edges
implicit def ad[A1 <% A](x: A1) = D(x.l :+ 'A')
implicit def bc[B1 <% B](x: B1) = C(x.l :+ 'B')
implicit def ce[C1 <% C](x: C1) = E(x.l :+ 'C')
implicit def ea[E1 <% E](x: E1) = A(x.l :+ 'E')
def pathFrom(end:D) = end
pathFrom(B(Nil)) // res0: D = D(List(B, C, E, A))
참고URL : https://stackoverflow.com/questions/5332801/how-can-i-chain-implicits-in-scala
'programing tip' 카테고리의 다른 글
Openstreetmap : 웹 페이지에지도 삽입 (예 : Google지도) (0) | 2020.10.17 |
---|---|
Amazon S3 파일 다운로드 이름 변경 (0) | 2020.10.17 |
Pandas 데이터 프레임에서 사용하는 메모리를 어떻게 해제합니까? (0) | 2020.10.17 |
메모리 매핑 파일의 장점은 무엇입니까? (0) | 2020.10.17 |
Scala의 다중 액터 구현은 어떻게 다릅니 까? (0) | 2020.10.17 |