#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
, либо использовать флаг компилятора для включения функции.