หากคุณเพียงพยายามทำให้ชั้นเรียนของคุณใช้อินเทอร์เฟซที่เข้ากันไม่ได้สองอินเทอร์เฟซแยกกัน คุณจะต้องเขียน wrappers แทน ตัวอย่างเช่น
implicit case class ImplAsFoo(impl: Impl) extends Foo {
def asFoo = this
def doSomething: Int = 5
}
ตอนนี้คุณสามารถ
impl.asFoo
ที่ไซต์การใช้งานเพื่อสลับไปใช้การห่อ Foo
อย่างไรก็ตาม ในบางกรณี มันอาจจะเป็นธรรมชาติมากกว่าที่จะใช้รูปแบบคลาสของประเภทแทนเพื่อให้ฟังก์ชันการทำงานแบบเสียบได้:
trait IFoo[A] { def doSomething: Int }
trait IBar[A] { def doSomething: String }
// These need to be companions so :paste if you're using REPL
class Impl { def doSomething { println("Hey!") } }
object Impl {
implicit object FooImpl extends IFoo[Impl] { def doSomething = 5 }
implicit object BarImpl extends IBar[Impl] { def doSomething = "salmon" }
}
def needsFoo[A <: Impl: IFoo](a: A) = implicitly[IFoo[Impl]].doSomething
scala> needsFoo(new Impl)
res1: Int = 5
scala> (new Impl).doSomething
Hey!
มันไม่ทุกประการเหมือนกัน แต่ยังจัดการกับปัญหาของการมีการใช้งานที่แตกต่างกันโดยไม่ตั้งชื่อรูปแบบที่ทำให้คุณสะดุด (หากคุณต้องการ doSomething
ด้วยวัตถุ impl
คุณจะต้องส่งผ่านเป็นพารามิเตอร์ใน implicit object
ที่จัดการกรณีนั้น)
หากคุณมีคุณสมบัติอยู่แล้ว แน่นอนว่าสิ่งนี้จะไม่ช่วยคุณ แต่เมื่อคุณออกแบบตั้งแต่เริ่มต้น แทนที่จะมีลักษณะมากมายที่มีวิธีการที่เข้ากันไม่ได้ คุณอาจลองใช้คลาสประเภทแทน
สุดท้ายนี้ หากคุณอดไม่ได้ที่จะรวมสิ่งที่ยังไม่ได้พิมพ์หลายๆ อย่างมาปะปนกันจนคุณต้องเลือก Foo
คุณต้องคิดค้นรูปแบบที่ซับซ้อนมากขึ้น เช่น:
trait CanBeFoo { def asFoo: Foo }
trait Foo { def doSomething: Int }
// :paste these two together
class Impl extends CanBeFoo {
def doSomething { println("Ho!") }
def asFoo = ImplAsFoo(this)
}
case class ImplAsFoo(impl: Impl) extends Foo {
def doSomething = 6
}
val myList = List("salmon", new Impl, new Foo { def doSomething = 4 })
def doIt(f: Foo) { println(f.doSomething) }
myList.foreach {
case f: Foo => doIt(f)
case cf: CanBeFoo => doIt(cf.asFoo)
case _ => println("nuh-uh")
}
// Produces
// nuh-uh
// 6
// 4
คุณอาจต้องการแผนที่ระดับกลาง:
myList.map{ case cf: CanBeFoo => cf.asFoo; case x => x }.foreach{
case f: Foo => println(f.doSomething)
case _ => println("nuh-uh")
}
person
Rex Kerr
schedule
16.07.2013