Lambda详解->C+&py

”明月如霜,好风如水,清景无限 “

来总结一下,lambda表达式。

C++中的会看起来更详细。总的来说可以把lambda表达式理解为一种方便的自定义函数。

lambda的语法格式:

  • capture mutable ->return-type{statement}

[capture]:捕捉列表。捕捉列表总是出现在Lambda函数的开始处。作为编辑器判断lambda表达式的特征,这部分必须存在,不能省略。

1、空。没有使用任何函数对象参数,意思只是是只用{statement}:函数体的变量。

2、=。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this).不过是按值传递(即不会改变原变量)。而&则是按引用传递(会改变原变量,可以理解成传递了指针)。

3、var。放某些局部变量,默认为值传递,如需引用传递则前面加上&。

4、this。函数体内可以使用Lambda所在类中的成员变量。

5、混着用,但是注意不要有变量重复。错误举例:[=,a],如果a是个局部变量,则已经被=包含。比较常用正确举例[&,a]和[=,&a,&b]

  • (parameters):参数列表。就是正常的函数输入参数,没有参数时()可以省略,但是不建议省略().

  • mutable mutable或exception声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身),默认值传递为const.

  • ->return-type 返回值类型,当返回值为void,可省略(此时编译器可以自动推断出返回值类型)。要有返回值时,强烈建议加上。eg.

-> int{statement}

  • {statement} 函数主体,可以是空,但{}不可省略。

再看一下,python中的lambda表达式。

fun_1 = lambda x:lambda y:x + y
fun = fun_1(3)
print('fun_1:',fun_1)
print('fun:',fun)
print('fun_1(3):',fun_1(3))
print( fun(2) )
print( (fun_1(3))(2) )


这样看起来,python里的lambda简单多了,标志是关键字lambda,后面则是 (输入) :(输出)

 lambda argument_list: expression

argument_list是参数列表,它的结构与Python中函数(function)的参数列表是一样的。

expression是一个关于参数的表达式。表达式中出现的参数需要在argument_list中有定义,并且表达式只能是单行的。这个单行相对于C++{statement}而言,功能上似乎弱化了很多,决定了lambda函数不可能完成复杂的逻辑,但是这也是python简洁干练的体现。

但是在某些情况(build-in内置函数)就是很方便:

herolist_json = requests.get(url_json).json()  # 获取英雄列表json文件
##简单map函数的参数:map(function,list)
hero_name = list(map(lambda x: x['cname'], herolist_json))  # 提取英雄的名字
hero_number = list(map(lambda x: x['ename'],herolist_json))  # 提取英雄的编号

list=[i for i in range(1,10)]
sorted(list, key=lambda x: abs(x-5)) ###列表按照和5的距离排序

对于一些把函数地址作为对象的函数,使用lambda充当参数就特别爽。

这是不得不说,lambda函数的特点是匿名&高效。

下面再举个小例子:

#include <functional>
#include <iostream>

using namespace std;
class Test
{
public:
  int num;
public:
  Test()
  {
    num = 100;
  }
  void lambda_test()
{
    int  i_a = 3;
    int i_b = 5;

    auto fun1 = [](int value) { int i_a = 4;
      cout << "fun1__:i_a="<< value << "\n" << endl; };//没有捕获任何参数,这里int v相当于函数参数
                           // auto fun1 = [](int v){ cout << this->num<<i_a<<endl ; }; 报错:封闭函数局部变量不能在 lambda 体中引用,除非其位于捕获列表中  
    fun1(i_a);//通过函数调用
          //=按照副本引用this,还有当前块语句所有的局部变量,不可以赋值,但是可以读取
    auto fun2 = [=]() { 
      int i_a = 10;
      int i_b = 20;
      this->num = 200;
      cout << "fun2__:" << "num=" << this->num << " i_a=" << i_a << " i_b=" << i_b << "\n"<<endl; 
    };
    fun2();
    cout << "fun2__后lambda_test内修改后" << "num=" << this->num << " i_a=" << i_a << " i_b=" << i_b << "\n" << endl;
    //&按照引用的方式操作局部变量,this,可以赋值,可以读取
    auto fun3 = [&]() { this->num =300; i_a = 10; i_b = 20; cout << "fun3__:" << "i_a=" << i_a << "  i_b=" << i_b << "\n" << endl; };
    fun3();
    cout << "fun3__lambda_test内修改后num=" << this->num << " i_a=" << i_a << " i_b=" << i_b << "\n" << endl;
    //指定铺货的参数i_a 可读可写,i_b只读,this->num 无法访问
    auto fun4 = [&i_a, i_b]() { i_a = 13; cout<< "fun4__:" << "i_a=" << i_a << "  i_b=" << i_b << "\n" << endl; };
    fun4();
    cout << "fun4__lambda_test内修改后num=" << this->num << " i_a=" << i_a << " i_b=" << i_b << "\n" << endl;


  }
};
int main()
{
  //Test test = Test();
  //Test test;
  //(test).lambda_test();
  Test *test = new Test();
  (*test).lambda_test();

  //Test test = new Test();
  //(test).lambda_test();
  int val = 0;
  //auto const_val_lambda = [=]() {  val = 3; }; //直接用val会报错 ,只能新建val !!!
  //const_val_lambda();
  //cout << "const_val_lambda():" << val <<"\n" <<endl; 
  auto const_val_lambda = [=](){  int val = 3; }; //直接用val会报错 ,只能新建val !!!
  const_val_lambda();
  cout <<"const_val_lambda():val="<< val << "\n" << endl; // 

  auto mutable_val_lambda = [=]() mutable { val = 3; cout << "mutable_val_lambda()函数内部:val=" << val << "\n" << endl;  };
  mutable_val_lambda();
  cout << "main()调用mutable_val_lambda()后:val=" << val << "\n" << endl; // 0

  system("pause");
  return 0;
}


看起来还是很清楚的。最起码说清了:=和&的区别。至于this你观察一下num就能总结出来了。至于mutable则是自己看main函数里面的,最大的改变是mutable让[=]能在lambda内直接使用局部变量而不报错。但不改变是值传递的本质。以后看到lambda就不用慌了。
喜欢的话记得点赞&将公众号星标啊。

END

作者:不爱跑马的影迷不是好程序猿

   喜欢的话请关注点赞👇 👇👇 👇                     

在这里插入图片描述

壹句: 月寒日暖,来煎人寿

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Lambda表达式->,是Java 8中引入的一种函数式编程的特性。它可以简洁地表示一个匿名函数,可以作为参数传递给方法或函数Lambda表达式的结构可以根据需要有零个或多个参数,参数可以明确声明或根据上下文推断。参数需包含在圆括号内,参数之间用逗号相隔。当只有一个参数且其类型可推导时,圆括号可以省略。Lambda表达式的主体可以包含零条或多条语句,如果主体只有一条语句,花括号{}可以省略。Lambda表达式的返回类型与主体表达式一致。如果主体包含一条以上的语句,表达式必须包含在花括号{}中形成代码块,返回类型与代码块的返回类型一致。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Lambda 表达式](https://blog.csdn.net/xxdw1992/article/details/103903210)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [深入浅出 Java 8 Lambda 表达式](https://blog.csdn.net/u012910595/article/details/70833510)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值