Для значения дополнительного аргумента действительно ли возможно зависеть от другого аргумента в Scala

Делает любой знает, возможно ли что-то вроде этого в Scala:

case class Thing(property:String)

def f(thing:Thing, prop:String = thing.property) = println(prop)

Вышеупомянутый код не компилирует; предоставление ошибки error: not found: value thing в thing.property

Следующие шоу ожидаемое поведение:

f(Thing("abc"), "123") // prints "123"
f(Thing("abc"))        // prints "abc"

Я понимаю, что мог сделать prop аргумент Option[String] и сделайте регистрацию функционального определения, но я задавался вопросом, был ли путь вокруг этого с новой именованной поддержкой / поддержкой параметра по умолчанию в 2.8.0.

17
задан Vasil Remeniuk 12 November 2010 в 15:26
поделиться

3 ответа

Да, в Scala 2.8 это возможно. Вот цитата из проектного документа «Именованные аргументы и аргументы по умолчанию в Scala 2.8» :

Поскольку область действия параметра расширяется по всем последующим спискам параметров (и тело метода), по умолчанию выражения могут зависеть от параметров из предыдущих списков параметров (но не по другим параметрам в том же список параметров). Обратите внимание, что при использовании значение по умолчанию, которое зависит от более ранние параметры, фактические используются аргументы, а не значения по умолчанию аргументы.

def f(a: Int = 0)(b: Int = a + 1) = b // OK

И еще один пример:

def f[T](a: Int = 1)(b: T = a + 1)(c: T = b)
// generates:
// def f$default$1[T]: Int = 1
// def f$default$2[T](a: Int): Int = a + 1
// def f$default$3[T](a: Int)(b: T): T = b

В соответствии с этим ваш код может выглядеть следующим образом:

scala> case class Thing(property:String)
defined class Thing

scala> def f(thing:Thing)(prop:String = thing.property) = println(prop)
f: (thing: Thing)(prop: String)Unit

scala> f(Thing("abc"))("123")
123

scala> f(Thing("abc"))()
abc
20
ответ дан 30 November 2019 в 13:40
поделиться

Другое простое решение - просто перегрузить метод:

case class Thing (property: String)

def f(thing: Thing, prop: String) = println(prop)

def f(thing: Thing) = f(thing, thing.property)
1
ответ дан 30 November 2019 в 13:40
поделиться

Именно для этого предназначена опция . Вы можете использовать метод getOrElse перед вызовом метода или внутри метода f .

scala> val abc = Some("abc")
abc: Some[java.lang.String] = Some(abc)

scala> val none: Option[String] = None
none: Option[String] = None

scala> println(abc getOrElse "123")
abc

scala> println(none getOrElse "123")
123

scala> def f(o: Option[String]) = println(o getOrElse "123")
f: (o: Option[String])Unit

scala> f(abc)
abc

scala> f(none)
123

Вот что вы можете сделать с помощью аргументов по умолчанию:

scala> case class Thing(property: String = "123")
defined class Thing

scala> def f(t: Thing) = println(t.property)
f: (t: Thing)Unit

scala> f(Thing("abc"))
abc

scala> f(Thing())
123

Ожидаемого поведения можно добиться с помощью простой перегрузки. Мне нужно было поместить метод в объект , потому что похоже, что REPL не разрешает прямое объявление перегруженных функций:

scala> object O {
         def overloaded(t:Thing) = println(t.property)
         def overloaded(t:Thing,s:String) = println(s)
       }
defined module O

scala> O.overloaded(Thing("abc"), "123")
123

scala> O.overloaded(Thing("abc"))
abc
0
ответ дан 30 November 2019 в 13:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: