Scala中至少有两种技术可以将默认值传递给方法
1)默认参数值
scala> def f(i: Int = 0) = i
f: (i: Int)Int
scala> f()
res0: Int = 0
scala> f(1)
res1: Int = 1
2)隐含参数
scala> def g(implicit i: Int) = i
g: (implicit i: Int)Int
scala> implicit val default = 0
default: Int = 0
scala> g(1)
res5: Int = 1
scala> g
res7: Int = 0
在哪种情况下你选择一个或另一个? 凭借隐式的力量,默认值是一个有用的功能吗?
答案 0 :(得分:12)
你绝对应该更喜欢默认参数值。
Int
或String
等常规类型的隐式参数。见下面的引文。另请参阅:Programming In Scala 21.5 Implicit parameters/A style rule for implicit parameters:
作为样式规则,最好在隐式参数的类型中使用自定义命名类型。
答案 1 :(得分:8)
其他答案很有意思,它们提出了有效点,暗示了编译时间变慢和代码更复杂。
但是,我认为重要的是要理解,从某种意义上说,隐含和默认是互补的:
当然,库可能会提供其函数将使用的含义 - 您在Scala库中始终使用implicits而不必定义它们,对吗?
然而,当使用implicits时,调用者总是可以指定不同的"默认"使用。
在任何一种情况下,都可以在调用函数时显式传递该值。
另一个小的区别是,人们可以选择通过命名参数覆盖哪些默认值,但如果您选择明确传递一个默认值,则必须传递所有默认值。
最后,请注意您可以同时使用隐式和默认值。
答案 2 :(得分:1)
如果声明默认值,那么您将始终拥有相同的默认值。使用implicits,默认值将取决于函数的使用位置。 例如,如果您提供这样的功能:
def listen(host:String, port:Int = 26000){ ...}
如果没有指定,使用此功能的人将侦听端口26000。 使用implicits,此函数的用户可以为该值定义自己的默认值:
//imagine this is defined in a library
def listen(host:String, implicit port: Int ) { .. }
//this is your code which uses that library
implicit val port = 410000
...
listen("localhost") //will use 41000
现在,在另一个包上,您可以使用不同的隐式:
implicit val port = 15000
listen("localhost") //will use 150000
这样,您可以使您的功能更加灵活,但这一切都取决于能否覆盖该值是否有意义。
您也可以将两者结合起来:
def f(implicit i: Int = 260000)
这将使用隐式值(如果可用)或默认值为26000(如果没有)。