Может ли неявный def использоваться функцией, у которой нет неявного параметра?

#scala #implicit-conversion #implicit

#scala #неявное преобразование #неявный

Вопрос:

Я наткнулся на этот блок кода в этом блоге . Я хочу знать, как h1("Hello World") она может компилироваться с тех пор h1(children: Frag*) .

 object TheirCode{
  trait Frag{
    def render: String
  }
  // HTML constructors
  def div(children: Frag*): Frag
  def p(children: Frag*): Frag
  def h1(children: Frag*): Frag
  ...
  implicit def stringFrag(s: String): Frag
}

object MyCode{
  import TheirCode._
  val frag = div(
    h1("Hello World"),
    p("I am a paragraph")
  )
  frag.render // <div><h1>Hello World</h1><p>I am a paragraph</p></div>
}
  

Я предполагаю implicit def stringFrag , что автоматически преобразуется h1(String) в h1(Frag) , но я всегда думал, что параметру метода потребуется неявный префикс, чтобы это работало (т. Е. implicit h1(children: Frag*) )

Комментарии:

1.Нет, вы путаете implicit значения (или аргументы) с implicit преобразованиями. Надеюсь, что эти материалы помогут. Кстати, в этом случае автор использует implicit преобразования для моделирования шаблона магнита.

2. div(h1("Hello World"), p("I am a paragraph")) на самом деле div(h1(stringFrag("Hello World")), p(stringFrag("I am a paragraph"))) . Нет необходимости в h1 том, p чтобы быть неявным. Достаточно того, что stringFrag неявно.

Ответ №1:

В этом случае мы вообще не говорим о неявных параметрах, а скорее о неявных преобразованиях. Всякий раз, когда компилятор находит A , но нуждается в B , он может автоматически применить функцию формы implicit def func(_: A): B , чтобы сделать возможным преобразование / присвоение.

Простой пример:

 implicit def string2int(s: String): Int = s.toInt
val i: Int = "2"
  

Обратите внимание, что для того, чтобы это работало, вам нужно либо явно импортировать scala.language.implicitConversions , либо использовать флаг компилятора для включения функции.