Всегда ли значения параметров по умолчанию всегда важнее в Scala?
def foo(implicit i: Int = 1) = i
def bar(implicit j: Int) = foo()
bar(4)
Этот кусок кода оценивается как 1
, Таким образом, значение по умолчанию имеет приоритет над неявным j
, который создается 4
, Поэтому кажется, что, по крайней мере, в этом примере значение параметра по умолчанию превосходит implicit
, делая определение foo
эквивалентно def foo(i: Int = 1) = i
,
Всегда ли значения параметров по умолчанию всегда важнее? Если да, то почему этот код является законным (учитывая, что он сбивает с толку)? Если нет, то каков контрпример?
Есть ли способ получить другое поведение, то есть фрагмент кода, аналогичный приведенному выше (со значением по умолчанию для i
) оценил бы 4
без явной передачи аргумента?
2 ответа
implicit
применяется ко всему списку параметров, а не только к одному параметру (например, вы можете иметь foo(implicit i: Int, j: Int)
, и оба параметра неявны, но, если вы хотите, чтобы был только один из них, вам придется разделить их на два списка: def foo(i: Int)(implicit j: Int)
,
Итак, чтобы передать неявные параметры в функцию, вы должны опустить весь список: foo
не foo()
,
Когда у тебя есть def foo(implicit i: Int)
, foo()
даже не компилируется, потому что вы пытаетесь отправить пустой параметр в список. foo
делает (пока неявный int находится в области видимости), потому что список передается неявно.
С def foo(implicit i: Int = 1)
, оба используют компиляцию, но означают разные вещи. foo()
означает "вызов foo
со значениями по умолчанию для всех параметров ", foo
означает "вызов foo
, передавая неявный список параметров ".
Итак, с bar(implicit j: Int) = foo
это будет оценивать в значение j
, в то время как bar(implicit j: Int) = foo()
оценивается в 1.
Компилятор Scala путается между implicit
и значение по умолчанию. foo()
заставляет компилятор игнорировать implicit
, так просто foo
делает трюк здесь
def foo(implicit i: Int = 1) = i
def bar(implicit j: Int) = foo
println(bar(5))
Результат: 5