什么是高阶函数?
在scala中,函数可以作为参数来传递。下面的代码定义一个接受函数作为参数的函数:
// 函数定义
def operation(func:(Int, Int) => Int) = {
val result = func(4,4)
println(result)
}
// 接下来,定义一个与预期签名匹配的函数:
val add = (x: Int, y:Int) => { x + y }
// 将add函数作为参数传递给operation函数
operation(add)
// 以上可以简写,相当于 val func = (x: Int, y:Int) => { x + y }
operation((x: Int, y:Int) => { x + y })
能接收函数参数的函数,或者返回值为函数的函数,称为”高阶函数”,比如这里的operation就是一个高阶函数。
下面定义一个返回一个函数的高阶函数:
def greeting() = {
println("any any ...")
(name: String) => {"hello" + " " + name} // 最后一行,是函数的返回值
}
// 调用函数greeting,得到它的返回值,这个返回值本身又是一个函数:
// 相当于 val func = (name: String) => {"hello" + " " + name}
val func = greeting()
// 调用func
func("朋友")
在这里,greeting函数就是一个“高阶函数”,因为它返回了一个函数。所以可以这样调用:
greeting()("朋友")
下面是另一个使用高阶函数的示例:
def functionOps3: Unit = {
// 1.匿名函数作为参数
def highOrderFunc(name:String, func:(String) => Unit): Unit = {
func(name)
}
highOrderFunc("xpleaf", (name:String) => println("Hello, " + name))
// 2.将匿名函数作为返回值传递给另外一个函数
def getGoodBayFunction(gMsg: String) = (gName: String) => println(gMsg + ", " + gName)
val goodbayFunction = getGoodBayFunction("good bye")
goodbayFunction("xpleaf")
}
functionOps3
call-by-name与call-by-value
本节是前一节高阶函数内容的延续,我们将展示按call-by-name和call-by-value函数参数之间的区别。
在下面的例子中,我们首先定义一个包含Tuple3元素的List,代表一组订单。我们定义一个函数循环遍历列表中的每个Tuple3元素来计算总成本。
假设商品在世界各地销售,因此需要将购买订单的总成本转换为使用的当地货币。我们分别定义了call-by-value函数参数调用和call-by-name函数参数的调用。请注意其中的区别。
import scala.util.Random
object demo {
// 定义一个placeOrder()函数,它将获取订单列表。
// 但是该函数还有一个exchangeRate参数,用于将总成本转换为当地货币。
// call-by-value
// 这意味着任何传递的汇率exchangeRate只会被计算一次
def placeOrder(orders: List[(String, Int, Double)])(exchangeRate: Double): Double = {
var totalCost: Double = 0.0
orders.foreach {order =>
val costOfItem = order._2 * order._3 * exchangeRate
println(s"Cost of ${order._2} ${order._1} = £$costOfItem")
totalCost += costOfItem
}
totalCost
}
// call-by-name
// 调用名称函数参数exchangeRate: => Double将在每次调用任何exchangeRate函数时计算它
def placeOrderWithByNameParameter(orders:List[(String, Int, Double)])(exchangeRate:=> Double):Double = {
var totalCost: Double = 0.0
orders.foreach {order =>
val costOfItem = order._2 * order._3 * exchangeRate
println(s"Cost of ${order._2} ${order._1} = £$costOfItem")
totalCost += costOfItem
}
totalCost
}
def main(args: Array[String]): Unit = {
val listOrders = List(("苹果", 5, 2.50), ("香蕉", 10, 3.50))
println(s"订单总费用 = £${placeOrder(listOrders)(0.5)}")
println(s"订单总费用 = £${placeOrderWithByNameParameter(listOrders)(0.5)}")
// 创建一个函数,它将随机生成美元USD到英镑GBP的货币转换
val randomExchangeRate = new Random(10)
def usdToGbp: Double = {
val rate = randomExchangeRate.nextDouble()
println(s"取美元对英镑的汇率 = $rate")
rate
}
// 调用call-by-name参数的函数
println(s"订单总费用 = £${placeOrderWithByNameParameter(listOrders)(usdToGbp)}")
// 对于列表中的每个订单,都将创建一个新的汇率,这是因为每次都在计算call-by-name函数usdToGbp函数
}
}
执行以上代码,输出结果如下:
Cost of 5 苹果 = £6.25
Cost of 10 香蕉 = £17.5
订单总费用 = £23.75
Cost of 5 苹果 = £6.25
Cost of 10 香蕉 = £17.5
订单总费用 = £23.75
取美元对英镑的汇率 = 0.7304302967434272
Cost of 5 苹果 = £9.13037870929284
取美元对英镑的汇率 = 0.2578027905957804
Cost of 10 香蕉 = £9.023097670852312
订单总费用 = £18.15347638014515
© 版权声明
本站网络名称:
知趣
本站永久网址:
https://www.qubaa.top
网站侵权说明:
本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长删除处理。
1 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
2 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
3 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
1 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
2 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
3 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
THE END
暂无评论内容