Scala重要知识

函数柯里化(Currying)

函数柯里化是一种将接受多个参数的函数转换成接受一个单一参数(最初函数的第一个参数)的函数,并返回接受余下的参数且返回结果的新函数的技术。这个技术由数学家Haskell Curry命名,它在函数式编程中非常有用,特别是在需要部分应用函数的场景。

例子:

考虑一个简单的函数,它接受两个参数并将它们相加:

def add(x: Int, y: Int): Int = x + y

柯里化后的版本会是这样:

def addCurried(x: Int)(y: Int): Int = x + y

你可以这样使用它:

val addOne = addCurried(1) // 这里addOne成为了一个函数,它接受一个Int类型的参数y,并返回1 + y的结果 println(addOne(5)) // 输出:6

在这个例子中,addCurried是一个柯里化的函数。首先使用一个参数调用它(例如:1),这会返回另一个函数,该函数接受第二个参数,并最终返回两个参数的和。


闭包(Closure)

闭包是一种函数,它可以捕获到其创建时所处上下文中的一个或多个变量的绑定。简单来说,闭包能够记住并访问其外部函数即使外部函数已经完成执行的变量。

例子:

def multiplier(factor: Int): Int => Int = { val multiplierFunction: Int => Int = (x: Int) => x * factor multiplierFunction }

这里,multiplier函数接受一个factor作为参数,并返回一个新的函数multiplierFunction。这个返回的函数接受一个整数x,并将其与factor相乘。

val timesTwo = multiplier(2) println(timesTwo(3)) // 输出:6

在这个例子中,timesTwo是一个闭包,它"记住"了factor参数(在这里是2),即使在multiplier函数已经执行完毕后。当调用timesTwo(3)时,它使用了当初multiplier被调用时的环境中的factor值。

函数柯里化和闭包是函数式编程中的两个非常重要的概念。柯里化允许你将函数的多个参数分解成更小的、可重用的部分。闭包则允许函数访问并操作函数外部的变量,即使这个函数已经执行完毕。这两个概念在Scala等支持函数式编程的语言中被广泛使用,为编写高度模块化和可重用的代码提供了强大的支持。


控制抽象

在Scala中,控制抽象是一种强大的语法特性,它允许你创建看起来像是语言原生支持的控制结构的方法。控制抽象能够使得你的代码更加灵活和表达力强,尤其是在需要创建自定义控制流结构时。

传值参数 vs 传名参数

你提供的代码示例展示了两种不同的参数传递方式:传值参数和传名参数。

  1. 传值参数:传值参数是最常见的参数传递方式,它意味着在调用函数时,实参的表达式会被立即求值,然后这个求值的结果被传递给函数。因此,不论函数内部如何使用这个参数,实参的表达式只会被求值一次。

    def f0(a: Int): Unit = { println("a: " + a) println("a: " + a) } f0(f1()) // f1()会被首先调用,然后将结果作为实际参数传递给f0

  2. 传名参数:传名参数不会在调用函数时立即求值,而是将未求值的表达式直接传递给函数。每次在函数体内访问这个参数时,表达式都会被求值。这就意味着如果函数体内多次使用该参数,表达式会被多次求值。

    def f2(a: => Int): Unit = { println("a: " + a) // 这里a会被求值 println("a: " + a) // 这里a会再次被求值 } f2(f1()) // f1()的调用被延迟,直到f2内部需要用到a的值时

控制抽象的意义

控制抽象的核心在于,它允许你将代码块作为参数传递给函数,而不仅仅是值或表达式。这种能力使得你可以创建出非常灵活的自定义控制结构。

在你的例子中,f2函数接受一个传名参数,这使得你可以传递一个代码块给它,就像传递给f2的最后一个调用那样:

f2({ println("这是一个代码块") 29 })

这里,整个花括号内的内容被视为一个整体,每次在f2函数内部访问a时,整个代码块都会被执行。

通过使用传名参数,Scala提供了一种强大的机制来实现控制抽象,允许开发者创建出类似于内建控制语句(如ifwhile等)的自定义控制流结构。这种特性极大地增强了语言的表达力和灵活性。

相关推荐
云深麋鹿5 分钟前
三.栈和队列
开发语言·数据结构·c++·算法
爆打维c10 分钟前
01BFS算法(例题:网格传送门旅游)
c语言·c++·python·算法·leetcode·广度优先
像素猎人17 分钟前
力扣:面试题16.01.交换数字
c++·算法·leetcode·面试
小O的算法实验室17 分钟前
2024年ASOC SCI2区TOP,异构 pbest 引导的综合学习粒子群算法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
咚为31 分钟前
Rust 错误处理的工程化演进:从 Result 到系统级边界设计
开发语言·后端·rust
qq_4061761432 分钟前
深入剖析JS中的XSS与CSRF漏洞:原理、攻击与防御全指南
服务器·开发语言·前端·javascript
AI科技星40 分钟前
从质能关系到时空几何:光速飞行理论的框架对比与逻辑验证
服务器·人工智能·线性代数·算法·矩阵
CSDN_RTKLIB1 小时前
C++仿函数
c++·算法·stl
qq_12498707531 小时前
基于Java的心理测试系统的设计与实现(源码+论文+部署+安装)
java·开发语言·vue.js·spring boot·计算机毕设·计算机毕业设计
学嵌入式的小杨同学1 小时前
【嵌入式 C 语言高频考点】周测 + 期中真题解析:从基础语法到编程实战
c语言·数据结构·数据库·vscode·算法·面试