Jadikan implisit dari objek berbeda dapat diakses saat objek saya diimpor

Ketika seseorang mengimpor objek saya, saya ingin beberapa kelas implisit dari objek (atau paket) lain tersedia untuk mereka. Memiliki import di objek tidak membantu, karena impor tidak diimpor secara transitif, oleh karena itu saya berasumsi saya harus menggunakan beberapa implicit def atau val, namun saya tidak dapat menemukan cara yang masuk akal untuk mencapai ini, hanya def yang cukup bertele-tele:

object Main extends App {

  object A {

    implicit class ExtendedMath(val x: Double) extends AnyVal {
      def square = x * x
    }

  }

  object X {

    import A._

    // what to write here, so that ExtendedMath is forwarded to our users?
    // following works, but it seems quite verbose
    implicit def extendedMath(x: Double): ExtendedMath = ExtendedMath(x)
  }


  import X._
  val a = 0.0
  println(a.square)
}

Apakah ada cara yang lebih ringkas?


person Suma    schedule 06.01.2016    source sumber
comment
Apakah Anda memiliki kendali atas paket yang ingin Anda ambil implisitnya?   -  person Michael Zajac    schedule 07.01.2016
comment
@ m-z Dalam kasus khusus ini saya melakukannya, tetapi saya dapat membayangkan terkadang seseorang ingin meneruskan implisit dari paket pihak ketiga.   -  person Suma    schedule 07.01.2016
comment
masukkan implisit ke dalam suatu sifat yang diperluas oleh kedua objek   -  person stew    schedule 07.01.2016


Jawaban (1)


Seperti yang disarankan @stew, pendekatan umumnya adalah mendefinisikan implisit dalam suatu sifat yang kemudian dapat Anda gabungkan beberapa kali. Satu-satunya peringatan adalah bahwa kelas nilai tidak diperbolehkan di dalam suatu sifat, jadi Anda harus memisahkan kelas nilai dan konversi implisit:

class ExtendedMath(val x: Double) extends AnyVal {
  def square = x * x
}

trait HasMath {
  // note: method name somehow must not shadow
  // value class name, therefore we use lower-case
  implicit def extendedMath(x: Double): ExtendedMath = new ExtendedMath(x)
}

object A extends HasMath

object X extends HasMath

object Test {
  import X._
  4.0.square
}
person 0__    schedule 07.01.2016
comment
jadi Anda harus memisahkan kelas nilai dan konversi implisit: - mengingat beban ini tidak ditanggung oleh pengguna objek, menurut saya ini dapat diterima. Jika ini adalah pendekatan yang umum, apakah ada namanya? - person Suma; 07.01.2016
comment
@Suma Saya tidak mengetahui adanya nama tertentu yang diberikan untuk pendekatan ini. Tapi saya sudah melihatnya berkali-kali jadi itu biasa. - person 0__; 07.01.2016