Lambda (chức năng) là gì?


743

Đối với một người không có nền tảng comp-sci, lambda trong thế giới Khoa học Máy tính là gì?


3
biểu hiện amda giải thích ở đây đẹp.
Jameer Mulani

1
hãy xem điều này để biết các hàm lambda trông như thế nào trong các ngôn ngữ khác nhau và vào năm nào chúng được giới thiệu bằng các ngôn ngữ đó.
Philip Schwarz

Câu trả lời:


1081

Lambda xuất phát từ tính toán Lambda và đề cập đến các hàm ẩn danh trong lập trình.

Tại sao điều này là mát mẻ? Nó cho phép bạn viết các hàm vứt đi nhanh chóng mà không cần đặt tên chúng. Nó cũng cung cấp một cách tốt đẹp để viết đóng cửa. Với sức mạnh đó bạn có thể làm những việc như thế này.

Con trăn

def adder(x):
    return lambda y: x + y
add5 = adder(5)
add5(1)
6

Như bạn có thể thấy từ đoạn mã của Python, trình bổ sung hàm nhận một đối số x và trả về một hàm ẩn danh, hoặc lambda, đưa ra một đối số y khác. Chức năng ẩn danh đó cho phép bạn tạo các chức năng từ các chức năng. Đây là một ví dụ đơn giản, nhưng nó nên truyền tải sức mạnh của lambdas và sự đóng cửa có.

Ví dụ trong các ngôn ngữ khác

Perl 5

sub adder {
    my ($x) = @_;
    return sub {
        my ($y) = @_;
        $x + $y
    }
}

my $add5 = adder(5);
print &$add5(1) == 6 ? "ok\n" : "not ok\n";

JavaScript

var adder = function (x) {
    return function (y) {
        return x + y;
    };
};
add5 = adder(5);
add5(1) == 6

JavaScript (ES6)

const adder = x => y => x + y;
add5 = adder(5);
add5(1) == 6

Kế hoạch

(define adder
    (lambda (x)
        (lambda (y)
           (+ x y))))
(define add5
    (adder 5))
(add5 1)
6

C # 3.5 trở lên

Func<int, Func<int, int>> adder = 
    (int x) => (int y) => x + y; // `int` declarations optional
Func<int, int> add5 = adder(5);
var add6 = adder(6); // Using implicit typing
Debug.Assert(add5(1) == 6);
Debug.Assert(add6(-1) == 5);

// Closure example
int yEnclosed = 1;
Func<int, int> addWithClosure = 
    (x) => x + yEnclosed;
Debug.Assert(addWithClosure(2) == 3);

Nhanh

func adder(x: Int) -> (Int) -> Int{
   return { y in x + y }
}
let add5 = adder(5)
add5(1)
6

PHP

$a = 1;
$b = 2;

$lambda = fn () => $a + $b;

echo $lambda();

Haskell

(\x y -> x + y) 

Java xem bài này

// The following is an example of Predicate : 
// a functional interface that takes an argument 
// and returns a boolean primitive type.

Predicate<Integer> pred = x -> x % 2 == 0; // Tests if the parameter is even.
boolean result = pred.test(4); // true

Lua

adder = function(x)
    return function(y)
        return x + y
    end
end
add5 = adder(5)
add5(1) == 6        -- true

Kotlin

val pred = { x: Int -> x % 2 == 0 }
val result = pred(4) // true

Hồng ngọc

Ruby hơi khác ở chỗ bạn không thể gọi lambda bằng cách sử dụng cú pháp chính xác giống như gọi hàm, nhưng nó vẫn có lambdas.

def adder(x)
  lambda { |y| x + y }
end
add5 = adder(5)
add5[1] == 6

Ruby là Ruby, có một tốc ký cho lambdas, vì vậy bạn có thể định nghĩa addertheo cách này:

def adder(x)
  -> y { x + y }
end

R

adder <- function(x) {
  function(y) x + y
}
add5 <- adder(5)
add5(1)
#> [1] 6

3
Vậy thì, sự khác biệt giữa hàm lambda và hàm functor là gì?
Tối nay 8/11/2016

1
@Maxpm một functor có thể là một đối tượng tiêu chuẩn với các trường và hàm cá thể, trong khi đó hàm lambda thường chỉ bao gồm một dòng hướng dẫn. Điều này có thể thay đổi tùy thuộc vào ngôn ngữ của khóa học.
zdimension

1
Tôi không nghĩ rằng nó nhất thiết phải chính xác để nói các hàm lambda giống như các hàm ẩn danh. Đối với một số ngôn ngữ như JavaScript, biểu thức lambda là một dạng cụ thể của hàm ẩn danh. Ví dụ JavaScript bạn đã cung cấp là một hàm ẩn danh không có cú pháp lambda trong khi ví dụ JavaScript (ES6) bạn đã cung cấp là biểu thức lambda.
Kyle Delaney

1
@KyleDelaney thực sự, ẩn danh không phải là điều kiện cần thiết để trở thành lambda, thực sự có chức năng lambda không ẩn danh, như bạn chỉ ra một ví dụ ngay cả trong ví dụ
Carmine Tambascia

@AliAnkarali hoặc quen với việc sử dụng rubys lambda;)
Jimmy MG Lim

107

Lambda là một loại hàm, được định nghĩa nội tuyến. Cùng với lambda, bạn cũng thường có một số loại biến có thể chứa tham chiếu đến hàm, lambda hoặc cách khác.

Chẳng hạn, đây là đoạn mã C # không sử dụng lambda:

public Int32 Add(Int32 a, Int32 b)
{
    return a + b;
}

public Int32 Sub(Int32 a, Int32 b)
{
    return a - b;
}

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, Add);
    Calculator(10, 23, Sub);
}

Cuộc gọi này được gọi là Máy tính, đi qua không chỉ hai số mà còn gọi phương thức nào bên trong Máy tính để lấy kết quả tính toán.

Trong C # 2.0, chúng tôi có các phương thức ẩn danh, rút ​​ngắn đoạn mã trên thành:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a + b;
    });
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a - b;
    });
}

Và sau đó trong C # 3.0, chúng ta đã có lambdas, làm cho mã thậm chí ngắn hơn:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, (a, b) => a + b);
    Calculator(10, 23, (a, b) => a - b);
}

Thay vì xác định rõ ràng đại biểu Op, người ta có thể chỉ cần sử dụngFunc<int, int>
Mateen Ulhaq

Tôi muốn đề xuất Console.WriteLine("Calculator: op " + op.Method.Name + " (" + a + ", " + b + ") = " + op(a, b));cho ví dụ đầu tiên.
Marc.2377

Thật đáng ngạc nhiên khi câu trả lời được chấp nhận là giúp mọi người bằng nhiều ngôn ngữ khác nhau, tôi cảm thấy câu trả lời này giúp tôi hiểu rõ hơn về lợi thế của lambdas và cách chúng khác với chức năng tiêu chuẩn. Tôi có thể thấy rõ lợi thế của lambda so với các phương pháp trước đây để có được kết quả tương tự.
RTHarston

Cảm ơn ví dụ của bạn, có một chức năng phức tạp hơn giúp hiểu được những lợi thế của lambdas hơn rất nhiều so với các chức năng đơn giản trong đó có vẻ như bạn không nhận được nhiều tối ưu hóa
Sarah

71

Cái tên "lambda" chỉ là một cổ vật lịch sử. Tất cả chúng ta đang nói đến là một biểu thức có giá trị là một hàm.

Một ví dụ đơn giản (sử dụng Scala cho dòng tiếp theo) là:

args.foreach(arg => println(arg))

trong đó đối số của foreachphương thức là một biểu thức cho một hàm ẩn danh. Dòng trên ít nhiều giống như viết một cái gì đó như thế này (không hoàn toàn là mã thực, nhưng bạn sẽ có ý tưởng):

void printThat(Object that) {
  println(that)
}
...
args.foreach(printThat)

ngoại trừ việc bạn không cần bận tâm đến:

  1. Khai báo hàm ở một nơi khác (và phải tìm nó khi bạn xem lại mã sau).
  2. Đặt tên một cái gì đó mà bạn chỉ sử dụng một lần.

Khi bạn đã quen với các giá trị hàm, việc phải làm mà không có chúng có vẻ ngớ ngẩn như được yêu cầu đặt tên cho mọi biểu thức, chẳng hạn như:

int tempVar = 2 * a + b
...
println(tempVar)

thay vì chỉ viết biểu thức nơi bạn cần nó:

println(2 * a + b)

Ký hiệu chính xác thay đổi từ ngôn ngữ này sang ngôn ngữ khác; Hy Lạp không phải lúc nào cũng được yêu cầu! ;-)


62

Nó đề cập đến phép tính lambda , là một hệ thống chính thức chỉ có các biểu thức lambda, đại diện cho một hàm lấy một hàm cho đối số duy nhất của nó và trả về một hàm. Tất cả các hàm trong phép tính lambda đều thuộc loại đó, nghĩa làλ : λ → λ .

Lisp đã sử dụng khái niệm lambda để đặt tên theo nghĩa đen của hàm ẩn danh. Lambda này đại diện cho một hàm có hai đối số x và y và trả về sản phẩm của họ:

(lambda (x y) (* x y)) 

Nó có thể được áp dụng nội tuyến như thế này (ước tính đến 50 ):

((lambda (x y) (* x y)) 5 10)

Tôi nghĩ rằng việc sử dụng của bạn λ : λ -> λlà khó hiểu (và thực sự không hợp lệ).
einpoklum

51

Tính toán lambda là một lý thuyết toán học thay thế phù hợp. Trong toán học, người ta thấy ví dụ x+y=5được ghép nối với x−y=1. Cùng với các cách để thao tác các phương trình riêng lẻ, cũng có thể kết hợp thông tin từ hai phương trình này với nhau, với điều kiện thay thế phương trình chéo được thực hiện một cách hợp lý. Phép tính Lambda mã hóa cách chính xác để thực hiện các thay thế này.

Cho rằng đó y = x−1là sự sắp xếp lại hợp lệ của phương trình thứ hai, điều này: λ y = x−1có nghĩa là một hàm thay thế các ký hiệu x−1cho ký hiệu y. Bây giờ hãy tưởng tượng áp dụng λ ycho mỗi thuật ngữ trong phương trình đầu tiên. Nếu một thuật ngữ ysau đó thực hiện thay thế; Nếu không thì không làm gì cả. Nếu bạn làm điều này trên giấy, bạn sẽ thấy cách áp dụng điều đóλ y sẽ làm cho phương trình đầu tiên có thể giải được.

Đó là một câu trả lời mà không có bất kỳ khoa học máy tính hoặc lập trình.

Ví dụ lập trình đơn giản nhất tôi có thể nghĩ đến đến từ http://en.wikipedia.org/wiki/Joy_(programming_lingu)#How_it_works :

đây là cách hàm vuông có thể được định nghĩa trong ngôn ngữ lập trình mệnh lệnh (C):

int square(int x)
{
    return x * x;
}

Biến x là một tham số chính thức được thay thế bằng giá trị thực được bình phương khi hàm được gọi. Trong một ngôn ngữ chức năng (Lược đồ), chức năng tương tự sẽ được xác định:

(define square
  (lambda (x) 
    (* x x)))

Điều này khác nhau theo nhiều cách, nhưng nó vẫn sử dụng tham số chính thức x theo cùng một cách.


Đã thêm: http://imgur.com/a/XBHub

lambda


14

Hơi quá đơn giản: một hàm lambda là một hàm có thể được truyền qua các hàm khác và nó được truy cập logic.

Trong cú pháp C # lambda thường được biên dịch thành các phương thức đơn giản giống như các đại biểu ẩn danh, nhưng nó cũng có thể được chia nhỏ và đọc logic của nó.

Chẳng hạn (trong C # 3):

LinqToSqlContext.Where( 
    row => row.FieldName > 15 );

LinqToSql có thể đọc hàm đó (x> 15) và chuyển đổi nó thành SQL thực tế để thực thi bằng các cây biểu thức.

Tuyên bố trên trở thành:

select ... from [tablename] 
where [FieldName] > 15      --this line was 'read' from the lambda function

Điều này khác với các phương thức bình thường hoặc đại biểu ẩn danh (thực sự chỉ là ma thuật trình biên dịch) bởi vì chúng không thể được đọc .

Không phải tất cả các phương thức trong C # sử dụng cú pháp lambda đều có thể được biên dịch thành các cây biểu thức (tức là các hàm lambda thực tế). Ví dụ:

LinqToSqlContext.Where( 
    row => SomeComplexCheck( row.FieldName ) );

Bây giờ cây biểu thức không thể được đọc - Một sốComplexCheck không thể bị phá vỡ. Câu lệnh SQL sẽ thực thi mà không có vị trí và mọi hàng trong dữ liệu sẽ được đưa vào SomeComplexCheck.

Các hàm Lambda không nên bị nhầm lẫn với các phương thức ẩn danh. Ví dụ:

LinqToSqlContext.Where( 
    delegate ( DataRow row ) { 
        return row.FieldName > 15; 
    } );

Cái này cũng có chức năng 'nội tuyến', nhưng lần này nó chỉ là ma thuật trình biên dịch - trình biên dịch C # sẽ phân tách nó thành một phương thức cá thể mới với một tên được tạo tự động.

Các phương thức ẩn danh không thể được đọc và do đó logic không thể được dịch ra vì nó có thể cho các hàm lambda.



7

Một ví dụ về lambda trong Ruby như sau:

hello = lambda do
    puts('Hello')
    puts('I am inside a proc')
end

hello.call

Sẽ tạo ra đầu ra sau:

Hello
I am inside a proc

5

@Brian Tôi sử dụng lambdas mọi lúc trong C #, trong các toán tử LINQ và không LINQ. Thí dụ:

string[] GetCustomerNames(IEnumerable<Customer> customers)
 { return customers.Select(c=>c.Name);
 }

Trước C #, tôi đã sử dụng các hàm ẩn danh trong JavaScript để gọi lại các hàm AJAX, trước khi thuật ngữ Ajax thậm chí được đặt ra:

getXmlFromServer(function(result) {/*success*/}, function(error){/*fail*/});

Tuy nhiên, điều thú vị với cú pháp lambda của C # là kiểu của chúng không thể được suy ra (nghĩa là bạn không thể gõ var foo = (x, y) => x * y) nhưng tùy thuộc vào loại chúng được gán cho, chúng sẽ được biên dịch thành các đại biểu hoặc các cây cú pháp trừu tượng đại diện cho biểu thức (đó là cách các trình ánh xạ đối tượng LINQ thực hiện phép thuật "tích hợp ngôn ngữ" của chúng).

Lambdas trong LISP cũng có thể được chuyển đến một toán tử trích dẫn và sau đó đi qua như một danh sách các danh sách. Một số macro mạnh mẽ được thực hiện theo cách này.


5

Câu hỏi được trả lời chính thức rất nhiều, vì vậy tôi sẽ không cố gắng thêm vào điều này.

Rất đơn giản, không chính thức cho một người biết rất ít hoặc không biết gì về toán học hoặc lập trình, tôi sẽ giải thích nó là một "cỗ máy" hoặc "chiếc hộp" nhỏ có một số đầu vào, làm cho một số công việc và tạo ra một số đầu ra, không có tên cụ thể , nhưng chúng tôi biết nó ở đâu và chỉ bằng kiến ​​thức này, chúng tôi sử dụng nó.

Thực tế mà nói, đối với một người biết chức năng là gì, tôi sẽ nói với họ rằng đó là chức năng không có tên, thường được đặt vào một điểm trong bộ nhớ có thể được sử dụng chỉ bằng cách tham chiếu đến bộ nhớ đó (thường thông qua việc sử dụng một biến - nếu họ đã nghe về khái niệm con trỏ hàm, tôi sẽ sử dụng chúng như một khái niệm tương tự) - câu trả lời này bao gồm những điều cơ bản đẹp (không đề cập đến việc đóng cửa, v.v.) nhưng người ta có thể nhận được điểm dễ dàng.



4

Chỉ vì tôi không thể thấy một ví dụ C ++ 11 ở đây, tôi sẽ tiếp tục và đăng ví dụ hay này từ đây . Sau khi tìm kiếm, đây là ví dụ cụ thể về ngôn ngữ rõ ràng nhất mà tôi có thể tìm thấy.

Xin chào, Lambdas, phiên bản 1

template<typename F>

void Eval( const F& f ) {
        f();
}
void foo() {
        Eval( []{ printf("Hello, Lambdas\n"); } );
}

Xin chào, Lambdas, phiên bản 2:

void bar() {
    auto f = []{ printf("Hello, Lambdas\n"); };
    f();
}

3

Tôi gặp khó khăn trong việc xoay quanh các biểu thức lambda vì tôi làm việc trong Visual FoxPro, có chức năng thay thế Macro và các hàm ExecScript {} và Evalu (), dường như phục vụ nhiều mục đích tương tự.

? Calculator(10, 23, "a + b")
? Calculator(10, 23, "a - b");

FUNCTION Calculator(a, b, op)
RETURN Evaluate(op)

Một lợi ích nhất định khi sử dụng lambdas chính thức là (tôi giả sử) kiểm tra thời gian biên dịch: Fox sẽ không biết nếu bạn đánh máy chuỗi văn bản ở trên cho đến khi nó cố chạy nó.

Điều này cũng hữu ích cho mã dựa trên dữ liệu: bạn có thể lưu trữ toàn bộ các thường trình trong các trường ghi nhớ trong cơ sở dữ liệu và sau đó chỉ cần đánh giá chúng vào thời gian chạy. Điều này cho phép bạn điều chỉnh một phần của ứng dụng mà không thực sự có quyền truy cập vào nguồn. (Nhưng đó là một chủ đề khác hoàn toàn.)


3

Đối với một người không có nền tảng comp-sci, lambda trong thế giới Khoa học Máy tính là gì?

Tôi sẽ minh họa nó bằng trực giác từng bước trong các mã python đơn giản và dễ đọc.

Nói tóm lại, lambda chỉ là một chức năng ẩn danh và nội tuyến.

Hãy bắt đầu từ bài tập để hiểu lambdasnhư một sinh viên năm nhất với nền tảng của số học cơ bản.

Bản thiết kế của bài tập là 'tên = giá trị', xem:

In [1]: x = 1
   ...: y = 'value'
In [2]: x
Out[2]: 1
In [3]: y
Out[3]: 'value'

'x', 'y' là tên và 1, 'giá trị' là giá trị. Hãy thử một hàm trong toán học

In [4]: m = n**2 + 2*n + 1
NameError: name 'n' is not defined

Báo cáo lỗi,
bạn không thể viết toán học trực tiếp dưới dạng mã, 'n' nên được xác định hoặc được gán cho một giá trị.

In [8]: n = 3.14
In [9]: m = n**2 + 2*n + 1
In [10]: m
Out[10]: 17.1396

Nó hoạt động ngay bây giờ, nếu bạn khăng khăng kết hợp hai dòng seperarte thành một. Có đếnlambda

In [13]: j = lambda i: i**2 + 2*i + 1
In [14]: j
Out[14]: <function __main__.<lambda>>

Không có lỗi báo cáo.

Đây là một cái nhìn thoáng qua lambda, nó cho phép bạn viết một hàm trong một dòng giống như bạn làm toán học trực tiếp vào máy tính.

Chúng ta sẽ thấy nó sau.

Hãy tiếp tục đào sâu hơn về 'nhiệm vụ'.

Như được minh họa ở trên, biểu tượng bằng =hoạt động cho loại dữ liệu đơn giản (1 và 'giá trị') và biểu thức đơn giản (n ** 2 + 2 * n + 1).

Thử cái này:

In [15]: x = print('This is a x')
This is a x
In [16]: x
In [17]: x = input('Enter a x: ')
Enter a x: x

Nó hoạt động cho các câu lệnh đơn giản, có 11 loại trong số đó trong python 7. Các câu lệnh đơn giản - Tài liệu Python 3.6.3

Làm thế nào về tuyên bố ghép,

In [18]: m = n**2 + 2*n + 1 if n > 0
SyntaxError: invalid syntax
#or
In [19]: m = n**2 + 2*n + 1, if n > 0
SyntaxError: invalid syntax

defcho phép nó hoạt động

In [23]: def m(n):
    ...:     if n > 0:
    ...:         return n**2 + 2*n + 1
    ...:
In [24]: m(2)
Out[24]: 9

Tada, phân tích nó, 'm' là tên, 'n ** 2 + 2 * n + 1' là giá trị. :là một biến thể của '='.
Tìm nó, nếu chỉ để hiểu, mọi thứ bắt đầu từ bài tập và mọi thứ là bài tập.

Bây giờ trở lại lambda, chúng ta có một hàm có tên 'm'

Thử:

In [28]: m = m(3)
In [29]: m
Out[29]: 16

Có hai tên của 'm' ở đây, hàm mđã có tên, trùng lặp.

Đó là định dạng như:

In [27]: m = def m(n):
    ...:         if n > 0:
    ...:             return n**2 + 2*n + 1
    SyntaxError: invalid syntax

Đây không phải là một chiến lược thông minh, vì vậy báo cáo lỗi

Chúng ta phải xóa một trong số chúng, đặt một hàm không có tên.

m = lambda n:n**2 + 2*n + 1

Nó được gọi là 'hàm ẩn danh'

Tóm lại là,

  1. lambda trong một hàm nội tuyến cho phép bạn viết một hàm theo một đường thẳng như trong toán học
  2. lambda là ẩn danh

Hi vọng điêu nay co ich.


2

Đó là một chức năng không có tên. Ví dụ: trong c # bạn có thể sử dụng

numberCollection.GetMatchingItems<int>(number => number > 5);

để trả về các số lớn hơn 5.

number => number > 5

là phần lambda ở đây. Nó đại diện cho một hàm lấy tham số (số) và trả về giá trị boolean (số> 5). Phương thức GetMatchingItems sử dụng lambda này trên tất cả các mục trong bộ sưu tập và trả về các mục phù hợp.


2

Trong javascript, ví dụ, các chức năng được coi là loại hỗn hợp giống như mọi thứ khác ( int, string, float, bool). Như vậy, bạn có thể tạo các hàm một cách nhanh chóng, gán chúng cho mọi thứ và gọi lại cho chúng sau. Nó hữu ích nhưng, không phải thứ bạn muốn sử dụng quá mức hoặc bạn sẽ nhầm lẫn tất cả những người phải duy trì mã của bạn sau khi bạn ...

Đây là một số mã tôi đang chơi để xem cái hố thỏ này sâu đến mức nào:

var x = new Object;
x.thingy = new Array();
x.thingy[0] = function(){ return function(){ return function(){ alert('index 0 pressed'); }; }; }
x.thingy[1] = function(){ return function(){ return function(){ alert('index 1 pressed'); }; }; }
x.thingy[2] = function(){ return function(){ return function(){ alert('index 2 pressed'); }; }; }

for(var i=0 ;i<3; i++)
    x.thingy[i]()()();

2

Trong ngữ cảnh của CS, hàm lambda là một khái niệm toán học trừu tượng giải quyết vấn đề đánh giá biểu tượng của các biểu thức toán học. Trong bối cảnh đó, hàm lambda giống như thuật ngữ lambda .

Nhưng trong ngôn ngữ lập trình thì có gì đó khác. Đó là một đoạn mã được tuyên bố là "tại chỗ" và có thể được thông qua như một "công dân hạng nhất". Khái niệm này có vẻ hữu ích để nó đi vào hầu hết các ngôn ngữ lập trình hiện đại phổ biến (xem các hàm lambda ở mọi nơi ).


2

A Lambda Function, hoặc a Small Anonymous Function, là một khối chức năng khép kín có thể được truyền qua và sử dụng trong mã của bạn. Lambda có tên gọi khác nhau trong các ngôn ngữ lập trình khác nhau - Lambdatrong PythonKotlin , Closuretrong Swift , hoặc Blocktrong CObjective-C . Mặc dù ý nghĩa của lambda khá giống nhau đối với các ngôn ngữ này, đôi khi nó có một chút khác biệt.

Hãy xem cách Lambda (Đóng) hoạt động trong Swift 4.2 với phương thức sort () - từ hàm bình thường cho đến biểu thức ngắn nhất:

let coffee: [String] = ["Cappuccino", "Espresso", "Latte", "Ristretto"]

1. Chức năng bình thường

func backward(_ n1: String, _ n2: String) -> Bool {
    return n1 > n2
}
var reverseOrder = coffee.sorted(by: backward)


// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]

2. Biểu thức đóng cửa

reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in
    return n1 > n2
})

3. Biểu thức đóng cửa nội tuyến

reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in return n1 > n2 } )

4. Suy ra loại từ bối cảnh

reverseOrder = coffee.sorted(by: { n1, n2 in return n1 > n2 } )

5. Trả về tiềm ẩn từ các lần đóng cửa đơn biểu hiện

reverseOrder = coffee.sorted(by: { n1, n2 in n1 > n2 } )

6. Tên đối số tốc ký

reverseOrder = coffee.sorted(by: { $0 > $1 } )

// $0 and $1 are closure’s first and second String arguments.

7. Phương thức vận hành

reverseOrder = coffee.sorted(by: >)

// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]

Hi vọng điêu nay co ich.


1

Tôi cũng hiểu rồi Tôi đã thử nó trong JS với cái này:

var addAndMult = function(x) {
        return (function(y) {
            return (function(z) {
                return (x+y)*z; 
                });
            });
        };

Nó thêm 2 đến 4 rồi ngắt kết quả bằng 6. Tuy nhiên tôi thấy đôi khi rất khó đọc :(

Ngoài ra tôi đã thực hiện một chức năng forEach thú vị:

var forEach = function(arr) {
            return (function(x) {
            for (var i=0; arr[i]; i++) {
                 x(arr[i]);
             }
        });
    }

forEach ([1,2,3,4,5]) (console.log);

Phương pháp này sẽ lặp lại một mảng và thực hiện một hành động - trong trường hợp in ra bàn điều khiển. Bây giờ tôi cũng hiểu tại sao labmdas mạnh mẽ.


1

Trong lập trình máy tính, lambda là một đoạn mã (câu lệnh, biểu thức hoặc một nhóm trong số chúng) lấy một số đối số từ nguồn bên ngoài. Nó không phải luôn luôn là một chức năng ẩn danh - chúng tôi có nhiều cách để thực hiện chúng.

Chúng ta có sự phân tách rõ ràng giữa các biểu thức, phát biểu và hàm, điều mà các nhà toán học không có.

Từ "hàm" trong lập trình cũng khác nhau - chúng ta có "hàm là một chuỗi các bước cần làm" (từ tiếng Latin "thực hiện"). Trong toán học, nó là một cái gì đó về mối tương quan giữa các biến.

Các ngôn ngữ hàm đang cố gắng giống với các công thức toán học nhất có thể và các từ của chúng có nghĩa gần giống nhau. Nhưng trong các ngôn ngữ lập trình khác, chúng tôi có nó khác nhau.


0

Câu hỏi đã được trả lời đầy đủ, tôi không muốn đi sâu vào chi tiết. Tôi muốn chia sẻ cách sử dụng khi viết tính toán số trong rỉ sét.

Có một ví dụ về lambda (hàm ẩn danh)

let f = |x: f32| -> f32 { x * x - 2.0 };
let df = |x: f32| -> f32 { 2.0 * x };

Khi tôi đang viết một mô-đun của phương pháp Newton Rap Raphson, nó được sử dụng như là đạo hàm bậc nhất và bậc hai. (Nếu bạn muốn biết phương pháp Newton Rap Raphson là gì, vui lòng truy cập " https://en.wikipedia.org/wiki/Newton%27s_method ".

Đầu ra như sau

println!("f={:.6}      df={:.6}", f(10.0), df(10.0))

f=98.000000       df=20.000000

0

Hãy tưởng tượng rằng bạn có một nhà hàng với tùy chọn giao hàng và bạn có một đơn hàng cần được thực hiện trong vòng dưới 30 phút. Vấn đề là khách hàng thường không quan tâm nếu bạn gửi thức ăn của họ bằng xe đạp bằng xe hơi hoặc chân trần miễn là bạn giữ ấm bữa ăn và buộc lại. Vì vậy, hãy chuyển đổi thành ngữ này sang Javascript với các chức năng vận chuyển ẩn danh và được xác định.

Dưới đây chúng tôi đã xác định cách phân phối của chúng tôi aka chúng tôi xác định tên cho một chức năng:

// ES5 
var food = function withBike(kebap, coke) {
return (kebap + coke); 
};

Điều gì xảy ra nếu chúng ta sử dụng các hàm mũi tên / lambda để thực hiện chuyển khoản này:

// ES6    
const food = (kebap, coke) => { return kebap + coke };

Bạn thấy không có sự khác biệt cho khách hàng và không lãng phí thời gian để suy nghĩ về cách gửi thực phẩm. Chỉ cần gửi nó.

Btw, tôi không đề xuất kebap với coke, đây là lý do tại sao các mã trên sẽ gây ra lỗi cho bạn. Chúc vui vẻ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.