Мы не можем смешивать неявные и неявные формальные параметры в списке параметров single , поскольку модификатор implicit
является свойством списка , а не параметр. Следовательно, следующее определение метода является недопустимым
def foo(msg: String, implicit n: Int) = ??? // Error
, однако, почему тогда следующее допустимое
class Foo(val msg: String, implicit val n: Int) // OK
Здесь представляется допустимым смешивать неявные и неявные параметры в одном параметре предложение при объявлении конструктора класса, однако модификатор implicit
действительно не применяется к формальному параметру n
, а вместо этого изменяет соответствующий автоматически созданный метод доступа member . Поскольку мы объявили n
равным val
, это расширяется до чего-то вроде
class Foo {
...
implicit def n(): Int = n;
def <init>(msg: String, n: Int) = { // note how msg and n are *NOT* implicit
...
}
}
, и совершенно законно объявить члена неявным. С другой стороны, если мы отбрасываем объявление val
, таким образом, не объявляя элемент, мы видим, что он не компилируется
class Foo(val msg: String, implicit n: Int) // Error: 'val' expected but identifier found ^
подобно тому, как это недопустимо в определении метода. Поэтому причина, по которой следующее не компилируется
implicit val num: Int = 4
new Foo("yo") // error: unspecified value parameter n
, заключается в том, что формальный параметр n
на самом деле не неявный.
Как сторона обратите внимание, что следующее Scala 2 требование
У метода или конструктора может быть только один неявный список параметров, и это должен быть последний заданный список параметров.
имеет было изменено Scala 3 Несколько заданных предложений
Может быть несколько заданных предложений параметров в определении, а заданные предложения параметров могут быть свободно смешивается с нормальными . Пример:
def f(u: Universe)(given ctx: u.Context)(given s: ctx.Symbol, k: ctx.Kind) = ...
, где given
соответствует implicit
.