18

有谁知道在 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参数设为 anOption[String]并在函数定义中进行检查,但我想知道是否有办法通过 2.8.0 中的新命名/默认参数支持来解决它。

4

3 回答 3

22

是的,在 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
于 2010-06-22T06:55:54.213 回答
2

另一个简单的解决方案就是重载方法:

case class Thing (property: String)

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

def f(thing: Thing) = f(thing, thing.property)
于 2010-06-22T08:09:20.243 回答
0

这正是Option它的用途。您可以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

可以通过简单的重载来实现预期的行为。我需要将该方法放在一个中,object因为它看起来像 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
于 2010-06-22T06:43:05.723 回答