Именованные аргументы Scala и аргументы по умолчанию в сочетании с неявными параметрами

Рассмотрим следующее:

def f(implicit a: String, y: Int = 0) = a + ": " + y
implicit val s = "size"
println(f(y = 2))

Последнее выражение вызывает следующую ошибку:

not enough arguments for method f: (implicit a: String, implicit y:
Int)java.lang.String. Unspecified value parameter a.

Однако если вы укажете значение по умолчанию для неявного параметра a, проблем не возникнет:

def f(implicit a: String = "haha!", y: Int = 0) = a + ": " + y
implicit val s = "size"
println(f(y = 2))

Но последняя строка печатает

haha!: 2

в то время как я ожидал

size: 2

Таким образом, неявное значение 's' не принимается. Если вместо этого вы не предоставляете какие-либо параметры для f и просто вызываете

println(f)

затем подбирается неявное значение, и вы получаете

size: 0

Может ли кто-нибудь пролить свет на то, что здесь происходит?


person Martin Studer    schedule 23.02.2012    source источник


Ответы (3)


Пытаться

println(f(y = 2, a = implicitly))

Как только вы начнете указывать параметры, вы не сможете вернуться назад. Либо весь список неявный, либо ни один из них.

person jsuereth    schedule 23.02.2012

Неявные параметры должны идти отдельно -- первыми, а в конце определения метода -- вторыми. Нравится:

def f(y: Int = 0)(implicit a: String) = a + ": " + y
implicit val s = "size"
println(f(y = 2))

Выходы

size: 2
person Vadim Samokhin    schedule 07.01.2013
comment
Чтобы использовать первый параметр по умолчанию, необходимо вызвать f() . - person raisercostin; 02.06.2015

В соответствии с тем, что сказал jsuereth, вы можете определить свою функцию как

def f(a: String = implicitly, y:Int = 0) = a + ": " + y

Или так, как я привык видеть,

def f(y:Int = 0)(implicit a: String) = a + ": " + y
person Dylan    schedule 23.02.2012
comment
Вы должны проверить, какую неявную область видимости использует неявно. Я не думаю, что это то же самое, что и второй вариант. - person jsuereth; 02.03.2012