В Scala неявное работает как :
конвертер
Значение параметра инжектора
Есть 3 типа использования Implicit
Неявное преобразование типов : оно преобразует присвоение с ошибкой в заданный тип
val x: String = "1"
val y: Int = x
String не является подтипом Int , поэтому в строке 2 происходит ошибка. Чтобы устранить ошибку, компилятор будет искать такой метод в области видимости, который имеет неявное ключевое слово, принимает в качестве аргумента строку и возвращает Int .
так
implicit def z(a:String):Int = 2
val x :String = "1"
val y:Int = x // compiler will use z here like val y:Int=z(x)
println(y) // result 2 & no error!
Неявное преобразование получателя : мы обычно вызываем свойства объекта получателя, например. методы или переменные. Таким образом, чтобы вызвать любое свойство получателем, оно должно быть членом класса / объекта этого получателя.
class Mahadi{
val haveCar:String ="BMW"
}
class Johnny{
val haveTv:String = "Sony"
}
val mahadi = new Mahadi
mahadi.haveTv // Error happening
Здесь mahadi.haveTv выдаст ошибку. Поскольку компилятор Scala будет первым искать haveTv имущества mahadi приемника. Это не найдет. Во-вторых, он будет искать метод в области видимости, имеющий неявное ключевое слово, которое принимает объект Mahadi в качестве аргумента и возвращает объект Johnny . Но это не имеет здесь. Так что это создаст ошибку . Но следующее хорошо.
class Mahadi{
val haveCar:String ="BMW"
}
class Johnny{
val haveTv:String = "Sony"
}
val mahadi = new Mahadi
implicit def z(a:Mahadi):Johnny = new Johnny
mahadi.haveTv // compiler will use z here like new Johnny().haveTv
println(mahadi.haveTv)// result Sony & no error
Неявное внедрение параметра : если мы вызываем метод и не передаем его значение параметра, это вызовет ошибку. Компилятор scala работает следующим образом - сначала попытается передать значение, но не получит прямого значения для параметра.
def x(a:Int)= a
x // ERROR happening
Во- вторых , если параметр имеет какое - либо ключевое слово неявный он будет искать любой Валу в рамках , которые имеют одинаковый тип значения. Если не получить, это приведет к ошибке.
def x(implicit a:Int)= a
x // error happening here
Чтобы решить эту проблему, компилятор будет искать неявный val, имеющий тип Int, потому что параметр a имеет неявное ключевое слово .
def x(implicit a:Int)=a
implicit val z:Int =10
x // compiler will use implicit like this x(z)
println(x) // will result 10 & no error.
Другой пример:
def l(implicit b:Int)
def x(implicit a:Int)= l(a)
мы также можем написать это как
def x(implicit a:Int)= l
Поскольку у l есть неявный параметр и в области видимости тела метода x есть неявная локальная переменная ( параметры являются локальными переменными ) a, которая является параметром x , поэтому в теле метода x значение неявного аргумента сигнатуры метода l равно поданный в локальном переменном неявном методе крестиков (параметр) a
неявно .
Так
def x(implicit a:Int)= l
будет в компиляторе, как это
def x(implicit a:Int)= l(a)
Другой пример:
def c(implicit k:Int):String = k.toString
def x(a:Int => String):String =a
x{
x => c
}
это вызовет ошибку, потому что c в x {x => c} требует явной передачи значения в аргументе или неявного val в области видимости .
Таким образом , мы можем сделать функцию литерал параметра явно неявно , когда мы называем метод х
x{
implicit x => c // the compiler will set the parameter of c like this c(x)
}
Это был использован в действии метод Play-Framework
in view folder of app the template is declared like
@()(implicit requestHreader:RequestHeader)
in controller action is like
def index = Action{
implicit request =>
Ok(views.html.formpage())
}
если вы не упоминаете параметр запроса как явный, то вы должны были написать
def index = Action{
request =>
Ok(views.html.formpage()(request))
}