exposir / TIL

📝 Today I Learned
https://exposir.github.io/blog/
4 stars 0 forks source link

test #148

Open exposir opened 9 months ago

exposir commented 9 months ago

概念 Lambda(λ)是一个重要的概念,广泛应用于数学、计算机科学和物理学等领域。在不同的领域中,它有着不同的含义:

  1. 数学:在数学中,λ通常表示一个特定的数值,如特征值、拉格朗日乘数等。
  2. 计算机科学:
    • Lambda 函数:在编程中,特别是在函数式编程语言中,lambda 函数或表达式是一种匿名函数,可以用于定义一些简单的函数操作,而无需命名。
    • Lambda 演算:是一种形式系统,用于研究函数定义、函数应用和递归,由阿隆佐·邱奇提出,对计算机科学的发展有重要影响。
  3. 物理学:在物理学中,λ经常用作波长的符号,表示电磁波、声波等波动现象的空间周期。 这个概念因其在不同学科中的广泛应用而变得非常重要。在计算机科学中,lambda 表达式为编程提供了更大的灵活性和表达能力,而在物理学中,它是描述波动现象的基本参数之一。在数学中,它则是用来表示特定数学对象的一个符号。 历史 在编程语言中,lambda 的历史可以追溯到20世纪中叶,与函数式编程的发展紧密相关。下面是一些关键的历史时刻:
  4. 早期理论基础:
    • 1930年代:阿隆佐·邱奇(Alonzo Church)发明了lambda 演算,这是一种形式化系统,用于研究函数抽象和应用,它是函数式编程的理论基础。
  5. LISP语言:
    • 1958年:John McCarthy 发明了 LISP 语言,它是第一个广泛采用 lambda 概念的编程语言。LISP 对函数式编程产生了深远影响,lambda 表达式在其中被用作匿名函数。
  6. Scheme 语言:
    • 1970年代:Scheme 语言的出现,它是 LISP 的一个方言,对 lambda 表达式的使用进行了标准化,进一步推广了函数式编程。
  7. ML和Haskell语言:
    • 1970年代和1980年代:ML 语言和 Haskell 语言的开发,这两种语言进一步强化了函数式编程的特性,包括对 lambda 表达式的支持。
  8. 流行语言中的采纳:
    • 1990年代至21世纪初:许多主流编程语言开始引入 lambda 表达式或匿名函数的概念。例如,Python、Ruby 和 JavaScript 逐渐加入了对匿名函数的支持。
  9. Java 8:
    • 2014年:Java 8 版本引入了 lambda 表达式,这是 Java 进入函数式编程领域的一个重要里程碑。
  10. C#和.NET:
    • 2000年代:C# 语言和 .NET 框架引入了 lambda 表达式,使得在这个平台上的函数式编程变得更加简单和强大。 总的来说,lambda 表达式在编程语言的发展中扮演了重要的角色,特别是在促进和简化函数式编程方面。从早期的理论基础到现代编程语言的实践应用,lambda 表达式一直是编程领域中的一个关键概念。 函数 Lambda 函数,也称为匿名函数或Lambda 表达式,是一种在许多编程语言中广泛使用的功能。Lambda 函数提供了一种简洁的方式来表示小型、未命名的函数。这些函数通常用于需要函数对象的场合,但又不希望为这些简单功能创建命名函数。 Lambda 函数的特点:
  11. 匿名性:Lambda 函数通常是匿名的,也就是说,它们没有显式的名称。
  12. 简洁性:Lambda 表达式通常很简短,它们用于实现一些简单的功能,如单行表达式或简单逻辑。
  13. 即用性:Lambda 函数通常在需要它们的地方定义和使用,这使得代码更加清晰、紧凑。
  14. 功能限制:与完整定义的函数相比,Lambda 函数通常功能更简单,有时可能有限制,例如无法包含多个语句或执行复杂的逻辑。 Lambda 函数在不同编程语言中的实现:
    • Python:使用 lambda 关键字定义。例如,lambda x: x * x 是一个计算平方的 Lambda 函数。
    • JavaScript:使用箭头函数语法。例如,(x) => x * x 是一个计算平方的箭头函数,它在行为上类似于 Lambda 函数。
    • Java:从 Java 8 开始,可以使用箭头符号 (->) 定义 Lambda 表达式。例如,(x) -> x * x 是一个 Lambda 表达式。 用途: Lambda 函数通常用于简化代码,特别是在涉及函数作为参数的场合,如高阶函数、事件处理、回调函数等。在函数式编程中,Lambda 表达式尤其常见,它们用于创建小的、用一次的函数,而不需要为每个小函数编写完整的定义。 举个例子,如果你有一个列表并想对其进行排序,但排序逻辑非常简单,使用 Lambda 函数就很方便。在 Python 中,你可以这样做: my_list = [(1, 'one'), (2, 'two'), (3, 'three')] my_list.sort(key=lambda x: x[1]) 在这个例子中,lambda x: x[1] 是一个 Lambda 函数,用于提取列表每个元素的第二个组成部分,以此作为排序依据。 Lambda 函数和普通函数有什么区别? Lambda 函数和普通函数在许多编程语言中都是重要的概念,它们都用于定义可以执行特定任务的代码块。虽然它们在功能上相似,但在定义方式、语法和用途上有一些关键的区别。以下是 Lambda 函数和普通函数之间的主要区别:
  15. 定义方式和语法:
    • Lambda 函数:通常是单行表达式,定义简洁。它们是匿名的,不需要通过名称来调用。Lambda 函数通常用于实现简单的、一次性的功能。
    • 普通函数:通常通过显式的名称定义,并可能包含多行代码。普通函数可以执行更复杂的操作,并且可以在代码的任何地方通过其名称被调用。
  16. 匿名性:
    • Lambda 函数:是匿名的,即没有具体的名称。它们通常在定义的地方立即使用。
    • 普通函数:通常有一个明确的名称,这个名称可以在代码中的任何地方引用该函数。
  17. 复杂性和功能范围:
    • Lambda 函数:适用于简单的任务,通常只包含一个表达式。它们不适合执行复杂的逻辑或包含多个语句。
    • 普通函数:可以执行更复杂的任务,包含多个语句、分支和循环。它们可以用于构建更复杂的功能。
  18. 作用域和可见性:
    • Lambda 函数:作用域通常限于它们被定义的地方,常用于小范围内的操作。
    • 普通函数:可以在定义它们的模块或类中的任何地方使用,甚至可以被其他模块或类导入和使用。
  19. 返回值:
    • Lambda 函数:自动返回其单个表达式的结果,无需显式使用 return 语句。
    • 普通函数:可以包含多个 return 语句,或者在没有 return 语句的情况下返回 None(在某些语言中)。
  20. 用途:
    • Lambda 函数:通常用于传递简单的函数作为参数,例如在高阶函数、排序操作或事件处理中。
    • 普通函数:用于定义可重用的代码块,适合实现更复杂的逻辑。 总结来说,Lambda 函数和普通函数在语法简洁性、复杂性、作用域和用途方面有明显的不同。Lambda 函数适用于实现快速、一次性的小功能,而普通函数适用于构建更复杂、可重用的代码逻辑。 Python 中使用 Lambda 函数 在 Python 中,Lambda 函数是一种快速定义单行的小函数的方式。Lambda 函数在 Python 中被称为 Lambda 表达式,它们是匿名的,意味着这些函数没有名字。Lambda 表达式在 Python 中主要用于需要函数对象的场合,但又不想在代码中分配额外的空间来命名这个函数。 基本语法: Lambda 表达式的基本语法是: lambda arguments: expression 这里,arguments 是传递给 Lambda 函数的参数列表,expression 是关于这些参数的表达式,它是函数的返回值。 使用示例:
  21. 简单的 Lambda 函数:

    一个简单的 Lambda 函数,计算两数之和

    add = lambda x, y: x + y print(add(5, 3)) # 输出:8

  22. 作为参数传递: Lambda 函数常用于那些需要函数作为参数的场合。例如,使用 map(), filter() 和 sorted() 等函数时:

    使用 Lambda 函数与 map 结合

    nums = [1, 2, 3, 4, 5] squared = list(map(lambda x: x ** 2, nums)) print(squared) # 输出:[1, 4, 9, 16, 25]

  23. 在列表推导式中使用: Lambda 函数也可以在列表推导式中使用,但这种用法较少见,因为列表推导式本身就是为了简化代码而设计的: nums = [1, 2, 3, 4, 5] squared = [(lambda x: x ** 2)(x) for x in nums] print(squared) # 输出:[1, 4, 9, 16, 25]
  24. 作为键值函数: 在排序或组织数据时,Lambda 函数可以作为键值函数(key function)使用:

    根据元素的第二个值进行排序

    pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')] pairs.sort(key=lambda pair: pair[1]) print(pairs) 这个例子中,Lambda 函数用于从每个元组中提取第二个元素作为排序的依据。 注意事项:

    • Lambda 函数适用于简单的逻辑,如果你的函数逻辑复杂,使用普通函数会更清晰。
    • 在可读性和维护性方面,过度使用 Lambda 函数可能会让代码难以理解,尤其是对于那些不熟悉 Lambda 表达式的开发者。
    • Lambda 表达式应该简洁明了,如果你发现自己正在编写一个复杂的 Lambda 表达式,考虑重构为普通函数。 Java 中的 Lambda 表达式 在 Java 中,Lambda 表达式是 Java 8 引入的一个重要特性,它允许你以更简洁的方式编写匿名函数。Lambda 表达式提高了代码的可读性和简洁性,特别是在处理集合、线程或事件处理器时。它们在函数式接口(只有一个抽象方法的接口)的上下文中使用。 基本语法: Java 中 Lambda 表达式的基本语法是: (parameters) -> expression 或者 (parameters) -> { statements; } 这里:
    • parameters 是参数列表,可以是零个或多个参数。
    • expression 是从 Lambda 表达式返回的表达式。
    • statements 是一个或多个 Java 语句。 如果 Lambda 表达式只有一个参数且没有类型声明,那么参数周围的括号可以省略。如果表达式只有一行,也可以省略大括号和 return 关键字。 使用示例:
  25. 无参数 Lambda 表达式: Runnable runnable = () -> System.out.println("Hello, World!"); new Thread(runnable).start(); 这里,Lambda 表达式被用作 Runnable 接口的实现,没有接收任何参数。
  26. 带参数的 Lambda 表达式: List names = Arrays.asList("John", "Jane", "Jack", "Diane"); names.forEach((name) -> System.out.println(name)); 这个示例中,Lambda 表达式接受一个参数 name 并打印它。
  27. 带复杂逻辑的 Lambda 表达式: Comparator stringComparator = (s1, s2) -> s1.compareTo(s2); Collections.sort(names, stringComparator); 这里,Lambda 表达式实现了 Comparator 接口,用于字符串比较。
  28. 返回值: 如果 Lambda 表达式中有多个语句,你需要使用大括号({})将这些语句括起来,并明确使用 return 语句来返回值。 BinaryOperator adder = (a, b) -> { int result = a + b; return result; }; System.out.println(adder.apply(5, 10)); // 输出:15 函数式接口: Java 中的 Lambda 表达式通常与函数式接口一起使用。函数式接口是只有一个抽象方法的接口,如 Runnable、Callable、Comparator 等。Java 8 引入了 @FunctionalInterface 注解,用于指示接口类型声明是一个函数式接口。 注意事项:
    • Lambda 表达式在 Java 中是类型安全的,编译器会根据上下文推断参数的类型。
    • 它们允许你将函数作为方法参数传递,提高代码的灵活性和表达力。
    • 使用 Lambda 表达式可以简化代码,特别是在处理集合或实现简单的接口时。
    • 过度使用或在复杂逻辑中使用 Lambda 表达式可能会降低代码的可读性。在这些情况下,使用传统的匿名内部类或命名类可能更合适。 JavaScript Lambda 函数 在 JavaScript 中,Lambda 函数通常指的是箭头函数(Arrow Functions),它们是 ES6(ECMAScript 2015)的一个新增特性。箭头函数提供了一种更简洁的方式来编写函数表达式,它们经常用于一些特定的场景,主要包括:
  29. 回调函数:
    • 在异步编程中,特别是处理诸如事件监听器、setTimeout、setInterval 或异步请求(如使用 fetch 或 XMLHttpRequest)时,箭头函数经常作为回调函数使用。
    • 例如,setTimeout(() => console.log("Hello"), 1000); 会在 1 秒后打印 "Hello"。
  30. 数组方法:
    • JavaScript 的数组原型上有许多内置方法,如 map、filter、reduce、forEach 等,这些方法接受回调函数作为参数。箭头函数在这些场合下非常有用,使代码更加简洁和易读。
    • 例如,[1, 2, 3].map(x => x * x) 会返回 [1, 4, 9]。
  31. 链式调用:
    • 在进行链式调用时,如在 Promise 链或使用类似于 jQuery 的库时,箭头函数可以简化代码。
    • 例如,在 Promise 中使用:fetch(url).then(response => response.json()).then(data => console.log(data));。
  32. 简单函数定义:
    • 对于那些不需要复杂逻辑或多个语句的简单函数,箭头函数提供了一种更简洁的定义方式。
    • 例如,const add = (a, b) => a + b; 是一个简单的加法函数。
  33. 匿名函数:
    • 在需要匿名函数的场合,如立即调用的函数表达式(IIFE),箭头函数是一个好选择。
    • 例如,(() => console.log('IIFE'))(); 是一个立即执行的箭头函数。
  34. 高阶函数和闭包:
    • 箭头函数可以用于创建高阶函数(即接受函数作为参数或返回函数的函数)或闭包。
    • 例如,const withLogging = fn => (...args) => { console.log(args); return fn(...args); }; 创建了一个高阶函数,它在调用另一个函数之前打印参数。
  35. 保持 this 上下文:
    • 箭头函数不绑定自己的 this,而是继承上下文中的 this 值。这在处理对象方法或在需要保持 this 上下文的事件处理器中非常有用。
    • 例如,在类方法中:class MyClass { method = () => { this.doSomething(); }; } 这里的箭头函数确保 this 指向 MyClass 的实例。 注意事项:
    • 虽然箭头函数在很多场景下非常有用,但它们并不总是普通函数的完美替代。例如,它们不适合用作方法(因为它们不绑定自己的 this),也不适合用作构造函数(因为它们不能使用 new 关键字)。
    • 简洁性和可读性应该保持平衡。在一些复杂的逻辑中,传统的函数表达式或函数声明可能更加合适。 剪头函数与匿名函数 在 JavaScript 中,术语 "Lambda 函数" 通常被用来指代箭头函数(Arrow Functions),这是从 ES6(ECMAScript 2015)起引入的一种新的函数语法。确实,"Lambda" 这个词在更广泛的编程领域中通常与匿名函数相关联,因为它源自 Lambda 演算,其中的函数是匿名的。在 JavaScript 的上下文中,箭头函数和匿名函数有一些相似之处,但也有区别。 箭头函数(Arrow Functions) 箭头函数是一种使用箭头 (=>) 语法简洁地写出函数的方式。它们可以是匿名的,但也可以被赋值给变量,从而具有名字。箭头函数的特点包括:
    • 简洁的语法:相比传统的函数表达式,它们通常更短。
    • 不绑定自身的 this:箭头函数不创建自己的 this 上下文,因此 this 的值由外围作用域决定。
    • 不绑定 arguments 对象:箭头函数不提供 arguments 对象,函数内部的 arguments 是从外部作用域继承的。 例如: javascriptCopy code let add = (a, b) => a + b; 匿名函数 匿名函数是没有名字的函数。在 JavaScript 中,传统的匿名函数通常使用 function 关键字定义。例如: javascriptCopy code let add = function(a, b) {return a + b; }; 这是一个匿名函数,因为它没有名称,但被赋值给了变量 add。 关系和区别
    • 箭头函数通常是匿名的:虽然箭头函数可以被赋值给变量(从而具有名称),但在定义时本身不带有名称。
    • 匿名函数不一定是箭头函数:传统的匿名函数使用 function 关键字定义,而箭头函数使用 => 语法。 因此,在 JavaScript 中,当人们提到 "Lambda 函数" 时,他们通常指的是箭头函数,这是一种特定的、通常是匿名的函数写法。但是,值得注意的是,"Lambda 函数" 这个术语在不同的编程语境中可能有不同的含义。在更广泛的编程文化中,它可能指任何形式的匿名函数。