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

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

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

在这里插入图片描述

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值