Всегда ли значения параметров по умолчанию всегда важнее в 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

Другие вопросы по тегам