C#:深入理解 lambda表达式与闭包

Lambda表达式以及变量捕获(java) Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。Lambda 表达式(Lambda expression),基于数学中的λ演算得名,也可称为闭包(Closure)。在学习Lambda表达式前要先了解下函数式接口。 阅读详情

1. Lambda表达式

1.1 简述Lambda表达式

Lambda表达式实际上是简化委托的写法,只要有委托参数类型的地方,就可以使用Lambda表达式表示。

为了比较委托写法与Lambda表达式的差异,实现两个int类型相加的委托进行对比:

委托写法:

Action<int, int> act = Add;
​
public static void Add(int a,int b)
{
    Console.WriteLine(a + b);
}

Lambda表达式:

Action<int, int> act = (a, b) => Console.WriteLine(a + b);

虽然Lambda表达式只是一个语法糖,在编码时有如下优点:

  • 更为简洁

  • 去除定义函数的中间过程,编码效率更高

  • 代码可读性、可维护性更强

1.2 Lambda表达式原理

Lambda表达式是语法糖,编译器在背后生成私有的密封类<>c,其中 <>9_5_0 定义委托静态变量,将委托方法包装成<.ctor>b_5_0 函数,用于委托绑定。Lambda表达式所在类中所有非闭包的代码都生成到<>c类中。

[Serializable]
 [CompilerGenerated]
 private sealed class <>c
 {
     ……
     public static Action<int, int> <>9__5_0;
​
     internal void <.ctor>b__5_0(int a, int b)
     {
        Console.WriteLine(a + b);
     }
     ……
 }
​
private Action<int, int> act = <>c.<>9__5_0 ?? (<>c.<>9__5_0 = new Action<int, int>(<>c.<>9.<.ctor>b__5_0));

2 闭包

2.1 定义

闭包是个准确而难懂的计算机名词,以下摘录不同书籍、文档中关于闭包的解释:

  1. 闭包就是能够读取其他函数内部变量的函数①。

  2. 通过Lambda表达式可以访问Lambda表达式代码块外部的变量,这称为闭包②。

  3. 闭包是由函数和与其相关的引用环境组合而成的实体。

笔者认为,第3点解释闭包更为直观。

2.2 闭包的原理

Lambda表达式可以在委托方法中,跨作用域访问类的成员、函数的局部变量、函数的入参。以下述代码为例:

public class Test 
{
    int Count = 0;
    
    Action CreateMessage(string message)
    {
        return () => { Console.WriteLine("Hello " + message + Count++); };
    }
}

当Action对象被调用的时候,CreateMessage方法已经返回了,作为它的实参的message应该已经被销毁了,为什么在调用返回的Action后,还是能够得到正确的结果呢?

这就是闭包的作用,通过函数和环境(string message)形成了一个新的类。通过IL代码,可以很清晰的看到,定义了为名为 <>c__DisplayClass3_0 的类,入参 message 被定义为类的成员变量,Test类中的Count成员通过 Test类型的成员变量 <>4_this 来使用。委托创建时,先创建 <>c_DisplayClass2的对象,并将方法中的局部变量赋值给了实例成员变量,将Test直接赋值给 <>c_DisplayClass2对象。

综上:闭包有延长变量生命周期作用。Lambda表达式中尽量使用局部变量,使用类成员会增加引用,容易引起对象生命周期变长,不利于内存释放。

public class Test
{
    [CompilerGenerated]
    private sealed class <>c__DisplayClass1_0
    {
        public string message;
​
        public Test <>4__this; // 引用的是对象,而非成员变量
​
        internal void <CreateMessage>b__0()
        {
            string text = message.ToString();
            Test test = <>4__this;
            int count = <>4__this.Count;
            test.Count = count + 1;
            Console.WriteLine(string.Concat("Hello ", text.ToString(), count.ToString()));
        }
    }
​
    private int Count = 0;
​
    private Action CreateMessage(string message)
    {
        <>c__DisplayClass1_0 <>c__DisplayClass1_ = new <>c__DisplayClass1_0();
        <>c__DisplayClass1_.message = message;
        <>c__DisplayClass1_.<>4__this = this;
        return new Action(<>c__DisplayClass1_.<CreateMessage>b__0);
    }
}

2.3 闭包共享数据

public void M() 
{
    List<Action> lists = new List<Action>();
​
    for (int i = 0; i < 5; i++)
    {
        lists.Add(() => { Console.Write(i); });
    }
​
    foreach (var i in Enumerable.Range(0, 5))
    {
        lists.Add(() => { Console.Write(i); });
    }
​
    foreach (var v in lists) v();
}
​运行上述代码,得到的结果是:5555501234;与预期的0123401234不一样,为什么会有这个现象呢?原因在于闭包构建的原理,闭包的构建在局部变量定义的位置,而不是Lambda表达式的位置。

按照老套路,看一波IL代码(使用C#1.0输出语言的版本),很直观的看到使用for循环时,只创建了一个对象 <>c_DisplayClass0,循环使用的变量是 <>c_DisplayClass0.i,局部变量i同时被5个闭包引用,这5个闭包共享i,所以最后他们打印出来的值是一样的,都是i最后退出循环时候的值5。

public void Method()
{
    List<Action> lists = new List<Action>();
    <>c__DisplayClass0_0 <>c__DisplayClass0_ = new <>c__DisplayClass0_0();  // 循环只定义一个对象
    <>c__DisplayClass0_.i = 0;
    while (<>c__DisplayClass0_.i < 5)
    {
        lists.Add(new Action(<>c__DisplayClass0_.<Method>b__0));
        <>c__DisplayClass0_.i++;
    }
    using (IEnumerator<int> enumerator = Enumerable.Range(0, 5).GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            <>c__DisplayClass0_1 <>c__DisplayClass0_2 = new <>c__DisplayClass0_1();  // 每次循环都定义一个对象
            <>c__DisplayClass0_2.i = enumerator.Current;
            lists.Add(new Action(<>c__DisplayClass0_2.<Method>b__1));
        }
    }
    foreach (Action v in lists)
    {
        v();
    }
}

从上述例子可知:存在闭包就等同于存在数据共享,共享数据的存在往往容易引起不预期的结果;存在共享就要警惕线程安全问题,尽量避免闭包在多线程环境的使用,应该使用更为明确函数定义。

附录

引用:

①:闭包_百度百科

②《C#高级程序编程(第9版)》8.3.3 闭包

工具:

ILSpy.exe

Lambda表达式详解(C#) Lambda表达式可以采用以下任意一种形式的表达式: 1.表达式Lambda,表达式为其主体: (input-parameters) => expression 2.语句Lambda,语句块作为其主体: (input-parameters) => {<sequence-of-statements>} 使用Lambda声明运算符=>,从其主体中分离Lambda参数列表。若要创建Lambda表达式,需要在Lambda运算符左侧指定输入参数(如果有参数时),然后在另一侧输入表达式 阅读详情

相关推荐

什么是逃逸闭包和非逃逸闭包?函数是闭包吗?闭包比函数简洁?Lambda?语言的“一等公民“?函数定义嵌套的意义?嵌套?Swift?

本文探讨了闭包、函数和嵌套等编程概念。闭包分为逃逸和非逃逸类型,本质上是匿名函数,比普通函数更简洁。函数在多数语言中是一等公民,支持赋值、传递等操作。文章比较了不同语言对函数嵌套定义的支持情况,如C++11引入lambda,Java支持Lambda表达式等。还介绍了嵌套类在C++、Java等语言中的实现。最后概述了Swift语言的发展历程,它融合多种编程范式,逐渐成为苹果生态的主流开发语言。全文通过对比多种编程语言特性,帮助理解这些核心编程概念。

编程语言开发、框架原理、编程思想、最佳实践技巧经验分享。致力于各种编程技术的技巧经验干货分享,讲解开发避坑技巧,追踪开发前沿技术,实战展开解决难题。 程序员小迷助您在编程路上越走越好! 898

C# Lambda表达式

Lambda表达式是C#语言中一种函数式编程的特性,它的主要作用是简化代码和提高代码的可读性。在使用Lambda表达式时,可以通过其内联特性来实现编写更加简洁的代码。下面将分别介绍Lambda表达式的语法和内联特性。Lambda表达式是一种匿名函数,它可以快速创建简单的委托或表达式树。在C#中,Lambda表达式通常用于替代匿名方法。Lambda表达式通常以箭头“=>”分隔左侧的输入和右侧的输出。

無限進步的全棧遊戲開發的博客 8631

Unity C#开发:匿名函数与Lambda表达式实战指南

在C#编程中,委托(Delegate)是函数式编程的基础概念,它允许将方法作为参数传递或存储为变量,为事件驱动和回调机制提供了核心支持。基于委托的原理,匿名函数和Lambda表达式进一步简化了代码结构,通过内联定义函数逻辑,减少了代码碎片化,提升了开发效率。这些技术在游戏开发领域具有重要价值,特别是在Unity引擎中,它们广泛应用于UI事件绑定、异步操作回调和数据查询处理等场景。通过闭包机制,Lambda能够捕获外部变量,实现更灵活的上下文交互,但同时也需注意内存分配和循环变量捕获等性能陷阱。本文聚焦Uni

weixin_30697239的博客 476

C# Lambda表达式各种用法总结

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 C# Lambda表达式前言一、使用Lambda 之前的示例二、使用Lambda 之后的示例然而Lambda可以将表达式更精简...另外两种Lambda表达式简化语法总结 前言 C# Lambda 作用 Lambda表达式可用于简化C#中的匿名语法 我们通过使用Lambda表达式前后委托的语法做比较 一、使用Lambda 之前的示例 此示例为委托的匿名方法声明不带Lambda表达式 namespace ConsoleApp3 { .

PittDing的博客 7702

C#深度解析:Lambda表达式与Func/Action委托的全方位指南

Lambda表达式是C#中用于定义匿名函数的一种简洁语法。它允许您在代码中直接内联编写小型、临时的函数,而无需显式定义一个完整的独立方法。Lambda表达式的语法由三个部分组成:输入参数列表、箭头符号=>以及表达式或语句块。Lambda表达式的基本结构Csharp:可选,表示Lambda接受的参数。可以是一个参数,多个参数(用逗号分隔),或没有参数(此时为空括号()=>:箭头符号,将参数列表与Lambda体分开。

java专栏 2454

【VAE学习笔记】全面通透地理解VAE(Variational Auto Encoder)

完整笔记:http://www.gwylab.com/note-vae.html 李宏毅老师的教程视频:https://www.bilibili.com/video/av15889450/?p=33 —————————————————————————————————   依据李宏毅老师的讲解,我整理了一番VAE的笔记。先简单介绍一下VAE,VAE作为一个生成模型,其基本思路是很容易理解的:把一堆真...

a312863063的博客 14万+

4.4-Lambda与闭包深入指南

本节将深入探讨C# Lambda表达式和闭包机制在游戏开发中的应用,帮助您理解函数式编程的核心概念,掌握现代C#编程中不可或缺的函数式编程技术。通过学习最新的C# 11/12特性,您将能够更优雅地处理游戏开发中的函数式编程场景。

qq_40263592的博客 1619

lisflood-fp(一)从源码到可执行文件:Windows下的Cmake实战编译指南

本文详细介绍了在Windows环境下使用Cmake工具编译lisflood-fp水文模型源码生成可执行文件的全过程。从开发环境配置、源码获取到实战编译,逐步指导如何解决常见错误并处理运行时依赖,最终生成可用的exe文件。特别适合水文专业研究者和工程师学习参考。

weixin_30555125的博客 480

深入理解Lambda表达式:基础概念与实战演练

在现代编程语言中,Lambda表达式作为一种轻量级的匿名函数形式,越来越受到程序员的青睐。特别是在函数式编程兴起的今天,Lambda表达式在简化代码、提高可读性方面发挥着重要作用。本文将深入探讨Lambda表达式的基础概念,并通过实际代码演示,帮助读者更好地理解和运用Lambda表达式。

一键难忘的博客 3451

学习笔记:物理信息神经网络(PINN)

PINN 的强大在于它打破了传统数值方法的限制,将神经网络的非线性拟合能力与物理方程的严谨性结合起来。它在处理高维、数据稀缺、复杂物理约束的场景下尤其出色。当然,PINN 也有收敛慢、梯度消失等挑战,比如,复杂 PDE 可能导致梯度传播困难,收敛慢(梯度消失)、于具有快速变化特征的系统,如冲击波,标准 PINN 可能精度不足,需要改进策略,比如自适应采样或多尺度特征提取。但随着研究深入,这些问题正在不断被解决。物理或化学方程为什么往往是偏微分方程?什么是物理信息神经网络(PINN)?x_%7Bi%7D。

qq_52635735的博客 1万+

无人机基本组成部件

无人机基本组成部件

qq_37410522的博客 1万+

【C#匿名方法与Lambda表达式深度解析】:掌握高效编程的两大利器

掌握C#匿名方法与lambda表达式,提升代码简洁性与执行效率。详解二者语法、适用场景及委托、事件中的实际应用,对比差异并演示LINQ等常用场景。深入理解函数式编程优势,优化开发效率,值得收藏。

IterStream的博客 902

FPGA高速接口Aurora8B/10B协议实战:从IP核配置到数据流优化

本文详细介绍了FPGA高速接口Aurora8B/10B协议的实战应用,从IP核配置到数据流优化的全流程。通过Aurora8B/10B协议,开发者可以在FPGA间实现高效的数据传输,适用于高速接口设计。文章涵盖了协议基础、IP核配置、AXI4-Stream接口实战技巧以及性能优化策略,帮助读者快速掌握这一关键技术。

weixin_29280657的博客 267

C# Lambda 闭包内存泄漏真相:80%团队都在犯的致命错误(附修复方案)

揭示C# Lambda闭包内存泄漏根源,提供可落地的修复方案。详解事件订阅、定时器等场景下的闭包陷阱,通过弱引用和作用域控制有效避免对象无法释放。掌握正确写法,提升应用性能,值得收藏。

VarFlow的博客 1109

基于STM32与CAN总线的多电机协同控制系统设计与实现

本文详细介绍了基于STM32与CAN总线的多电机协同控制系统设计与实现。该系统采用分布式架构,通过CAN总线实现多节点通信,结合梯形加减速算法和同步控制策略,有效解决了工业自动化中多电机同步性差的问题。文章涵盖硬件设计、通信协议、抗干扰措施及实战调试经验,为工业应用提供高可靠性解决方案。

tech5的博客 969

17track单号查询逆向分析

这就说明该网站很有可能存在其它检测点,而检测本地替换最大可能的就是检测了代码格式化或者代码长度。也一样,要么导致网站卡死,要么会导致网页加载异常,这里可能就难到不少人了,让我们一步一步解决。而这个站主要是检测了代码格式化,无限循环检测造成了网站卡死,经多次测试发现检测点共三处。方法中代码很长,但是经调试后发现,它其实只返回一个固定的值,这里直接写死即可。同样的,虽然看起来很长,但是跟过之后就会发现流程很简单,这里主要就是对。追加了一些值,是一条很长的语句,整理代码。,核心流程也很简单,稍微跟一下就出来了,

pyzzd的博客 1620

Lambda 表达式中的闭包陷阱(资深架构师亲授避坑指南)

揭秘C# Lambda闭包常见陷阱与解决方案,资深架构师亲授避坑指南。涵盖循环变量捕获、生命周期管理等典型场景,教你正确使用捕获机制避免内存泄漏。掌握安全编码实践,提升代码健壮性,值得收藏。

FuncInk的博客 698

上万条对话白分析了?智能客服质检避坑指南:90%团队倒在这些误区

当前客服质检普遍存在投入产出失衡的现象,根源在于十大误区:过度关注单点技术指标而忽视端到端解决能力、僵化的话术模板限制AI应变、数据孤岛阻碍知识进化、盲目追求拟人化牺牲效率、传统整改机制跟不上机器速度等。破局需重构质检体系,包括建立决策树质检法、设计复杂问题测试集、构建实时数据闭环、重置AI专属评价指标、实施分钟级热修复机制等。关键在于将质检从被动纠错升级为主动赋能,通过根因分析、场景化反馈、标准化评分和数据驱动优化,打造"问题诊断-改进-验证"

2202_75469062的博客 1541

C#中Lambda表达式多参数的极致运用(仅限高级开发者掌握的秘技)

掌握C# Lambda多参数的高级应用,提升代码简洁性与性能。适用于LINQ查询、事件处理及复杂委托场景,通过匿名函数实现多参数高效传递。深入解析语法细节与优化技巧,值得收藏。

VarFlow的博客 1019

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Unity C#入门:Lambda表达式的简化写法与应用

本文是《Unity工程师成长之路教程》系列中关于Lambda表达式简化写法与应用的入门指南。文章首先介绍了Lambda表达式在Unity开发中的核心概念和重要性,强调其对提升开发效率、游戏性能和问题解决能力的关键作用。随后详细讲解了技术原理,包括Unity架构概述和实现方法,并提供了组件化设计、生命周期函数等关键技术点的说明。实践部分包含环境准备步骤和两个基础示例:游戏对象控制和UI交互,通过代码演示了具体应用场景。本文适合Unity初学者系统学习Lambda表达式的简化写法与应用技巧。

编程世界如山海,探索不止。 1万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

你真的懂C#闭包吗?3个实战案例揭示Lambda背后隐藏的风险

掌握C# Lambda闭包的正确使用方法,避免常见陷阱。通过3个典型实战案例,解析闭包在事件处理、异步编程和循环中的应用与风险,揭示变量捕获机制的关键细节。提升代码稳定性与性能,值得收藏。

CompiLume的博客 610

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

C# Lambda 表达式知识干货整理

Lambda 表达式是 C# 3.0 引入的一种简洁的匿名函数写法,用于创建委托或表达式树。它的核心价值在于:用更少的代码表达「输入参数 → 处理逻辑 → 返回结果」这一过程,让代码更聚焦于业务逻辑本身。(参数列表) => 表达式或语句块其中=>读作「goes to」,左侧是输入参数,右侧是处理逻辑。// 传统委托写法// Lambda 写法。

Chuang_Mhan的博客 317

精通C# Lambda与LINQ:Unity数据处理效率提升10倍的秘诀! (第25天)

在之前的学习中,我们已经掌握了C#的基础语法、面向对象编程、数据结构以及委托与事件等核心概念。今天,我们将迈入一个让代码更简洁、数据处理更高效的新领域——Lambda表达式与LINQ(Language Integrated Query)。对于游戏开发而言,我们经常需要处理各种集合数据,例如查找场景中的所有敌人、筛选符合特定条件的物品、对玩家得分进行排序等。同时,事件处理也是交互逻辑的核心。

吴师兄大模型的博客 2038

学习笔记——C#的闭包

Lambda表达式实际上是简化委托的写法,只要有委托参数类型的地方,就可以使用Lambda表达式表示。

m0_63869023的博客 646

为什么你的异步任务总出错?揭秘Lambda闭包在循环中的诡异行为

掌握C# Lambda闭包在异步循环中的正确用法,避免常见错误。详解其捕获机制与生命周期问题,提供可靠解决方案,提升代码稳定性。适用于多线程、事件处理等场景,值得收藏。

LearnFlow的博客 970
上一篇: C#中的自定义控件中的属性、事件及一些相关特性的总结(转)
下一篇: 腾讯会议本地录屏转存失败解决办法
YoungProgrammer
博客等级 码龄12年 24粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值