我正在关注this教程,我看到了这段代码:
println("\nStep 1: How to define a higher order function which takes another function as parameter")
def totalCostWithDiscountFunctionParameter(donutType: String)(quantity: Int)(f: Double => Double): Double = {
println(s"Calculating total cost for $quantity $donutType")
val totalCost = 2.50 * quantity
f(totalCost)
}
println("\nStep 2: How to define and pass a def function to a higher order function")
def applyDiscount(totalCost: Double): Double = {
val discount = 2 // assume you fetch discount from database
totalCost - discount
}
println(s"Total cost of 5 Glazed Donuts with discount def function = ${totalCostWithDiscountFunctionParameter("Glazed Donut")(5)(applyDiscount(_))}")
println("\nStep 3: How to define and pass a val function to a higher order function")
val applyDiscountValueFunction = (totalCost: Double) => {
val discount = 2 // assume you fetch discount from database
totalCost - discount
}
println(s"Total cost of 5 Glazed Donuts with discount val function = ${totalCostWithDiscountFunctionParameter("Glazed Donut")(5)(applyDiscountValueFunction)}")
作者说:
该函数有一个by-name参数,该参数应该是一个具有Double类型参数的函数,并且还将返回一个Double类型。
这是真的吗?这里的按值参数是什么?该函数是否被懒惰地评估,使其成为一个名字参数?这是真的吗?
为什么作者在传递applyDiscount
时使用通配符,而不是在传入applydiscountValueFunction
时?两者都没有通配符操作符。
答案 0 :(得分:2)
applyDiscount(_)
使用占位符语法将匿名函数转换为函数。
只要期望函数类型并且传递方法,编译器(使用称为 eta-expansion 的技术)就可以自动执行此过程,这与示例中的情况完全相同。 / p>
(有关更全面的讨论,请参阅此答案:Underscore usage when passing a function in Scala)
所以你说这个
是对的totalCostWithDiscountFunctionParameter("Glazed Donut")(5)(applyDiscount)
无论如何都会工作,因为编译器会自动将applyDiscount
转换为函数。
根据by-name参数,作者调用的by-name
参数(参数f
)实际上只是Double => Double
类型的参数,所以看来他&#39 ; s使用不正确的术语。
Scala中的by-name参数使用=>
表达,如下所示:
def someMethod(someParam: => Double): Double = // ...
在此示例中,someParam
是一个名称参数,这意味着它不会在呼叫站点进行评估。