浅谈 Unity、iOS、Android 闭包的使用方法

简介: 浅谈 Unity、iOS、Android 闭包的使用方法

image.png

前言


我们经常所编程语言的的进步速度是落后于硬件的发展速度的。

但是最近几年,闭包语法在各个语言中都有自己的体现形式,如:

  •  C语言中使用函数指针作为回调函数的入口;

  •  Java和C#语言中的Lambda语法表达式;

  •  Objective-C语言中的Blocks语法;

  •  C#语言中的Delegates语法;

  •  C++语言中的Functions对象;

正文


历史由来


计算机的目的就是计算,也可以这样狭隘的理解,计算机要能完成可计算公式的计算和逻辑。要完成这样的事情,需要一套东西去支持。

阿隆佐邱奇(Alonzo Church)发明了Lambda演算,也就是λ演算

Lambda演算


λ演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义、函数如何被应用以及递归的形式系统。

因为这里Lambda演算不是讨论的重点,我举几个简单的例子,让大家明白就好。

在Lambda演算中,每个表达式都代表一个函数,这个函数有一个参数,并且会返回一个值。也就是说在Lambda演算中只有函数。

  1. Lambda演算的基本定义:
    λx. E,x是参数,并且有且仅有一个参数,E是函数体。
  2. 函数的应用:

     E1 E2,E1是个函数,E2也是个函数,并且每个函数都有返回值,E2的返回值当成λx. E的x,带人到E1的函数中,在返回E1的结果。

这样还是很难理解,再来个个例子。

现在我们定义一个数学函数f(x) = x + 2,数学意义很明显,就给x加上2。怎么用Lambda演算弄?

  1. Lambda演算的基本定义:
    λx. x + 2,x是参数,x + 2函数体。
  2. 函数的应用:
    当有个参数λa.a 3的时候就是这个样子(λx. x + 2) (λa.a 3),可以写成也就符合上面的E1 E2格式。结果就是(λx. x + 2)3 = 3 + 2 = 5

这里有没有特别的熟悉,说说编程函数定义。

1. returnValue funcitonName(parameter){
2.   methodBody
3. }

假如这个函数只能传入一个参数,那么是不是就是 λx. E的简单表达,原来函数的由来可以这样追溯。

使用方法


C++语言中的Functions对象:


#include <iostream>
#include <string>
#include <vector>
using namespace std;
//构造string向量
vector<string> GetNameList()
{
    static vector<string> names;
    names.push_back("刘辉");
    names.push_back("李静波");
    names.push_back("崔亚允");
    names.push_back("赵雅");
    names.push_back("管辉");
    names.push_back("白志刚");
    names.push_back("王斌");
    names.push_back("白雅静");
    names.push_back("张浩");
    return names;
}
void foo(string myname) {
    vector<string> names = GetNameList();
    //通过遍历string向量,使用闭包完成判断条件
    vector<string>::iterator i = find_if(names.begin(), names.end(), [&](const string& s){
        //判断操作值与参数相等是否相等
        return s == myname;
    });
    //输出判断得到的结果
    cout  <<(string)(*i) << endl;
}
int main(int argc, const char * argv[]) {
    foo("刘辉");
    return 0;
}

1、声明闭包变量

C++中闭包的声明语法,要使用 function 类型来声明变量,如下所示:

std::function<float(float)> colsure;

其中,第一个 float 代表了闭包的返回值类型,第二个 float 代表了闭包的参数数据类型为浮点型

2、赋值闭包变量

C++中闭包的赋值语法,要使用 [=] 或 [&] 符号开头,如下所示:

colsure = [=](float f) {
      f += 10.0f;
      return f;
};

其中, [=] 代表了我们将要进行的闭包传值是单向赋值

[&] 在使用过程中,经常作为引用传值使用,如下所示:

std:function<float(float&)> col;
col = [&](float& f){
      f += 10.0f;
      return f;      
};

3、使用闭包变量

使用 [=] 和 [&] 声明并且赋值后的闭包变量,在使用结束后的结果如下:

//声明一个浮点型变量
float floatValue = 1.0f;
//声明计算结果浮点型变量
float resultValue = 0.0f;
//使用[=]类型的闭包变量
resultValue = colsure(floatValue);
//输入结果
std::cout<<floatValue<<":"<<resultValue<<endl;
//使用[&]类型的闭包变量
resultValue = col(floatValue);
std::cout<<floatValue<<":"<<resultValue<<endl;

[=] 和 [&] 分别代表了值传递和引用传递的两种方式。

C#语言中的Lambda表达式:


Lambda表达式实在C#4中出现的语法糖,用来提高程序的开发效率,简化Func类型变量和delegate对象的写法。

常见的代码如下:

using System;
using System.Collections.Generic;
namespace LambdaSample
{
    class MainClass
    {
        public static List<string> GetNameList()
        {
            List<string> names = new List<string> ();
            names.Add ("刘辉");
            names.Add ("崔亚允");
            names.Add ("李静波");
            names.Add ("赵雅");
            names.Add ("管辉");
            names.Add ("白志刚");
            return names;
        }
        public static void foo(string myname)
        {
            //获取姓名列表
            List<string> names = GetNameList ();
            //通过Lambda表达式作为判断条件进行查询
            string result = names.Find ((x) => {
                return x == myname;
            });
            //输入查询结果
            Console.WriteLine(result);
        }
        public static void Main (string[] args)
        {
            //测试
            foo ("崔亚允");
        }
    }
}

1、声明C#语言中的Lambda表达式变量

在C#语言中,可以通过 Func 类型来声明Lambda变量,如下所示:

Func<float,float> func;

或者使用 delegate 类型来声明Lambda变量,如下所示:

//定义一个delegate类型Interface
delegate float Interface(float x);
public static void Main (string[] args)
{
     //使用Interface类型来声明Lambda变量
     Inteface inter_func;    
}

2、赋值C#语言中的Lambda表达式变量

在C#语言中,使用 => goes to 运算符来生成变量,如下所示:

func = (x) => {
    x += 10.0f;
    return x;
};

=> goes to运算符的左边是闭包类型的浮点型参数,右边是闭包变量准备进行的逻辑运算,以 {} 包括。

3、使用C#语言中的Lambda表达式变量

和调用函数一样,如下所示:

//声明Func类型变量
Func<float,float> func;
//为func赋值Lambda闭包
func = (x) => {
    x += 10.0f;
    return x;
};
float floatValue = 1.0f;
float resultValue = 0.0f;
//调用func变量,计算结果并且赋值给resultValue
resultValue = func (floatValue);
//进行输出
Console.WriteLine (resultValue);

总结


其实在计算机科学中,闭包Closure)是词法闭包Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。

注意咯:

闭包一词经常和匿名函数混淆。这可能是因为两者经常同时使用,但是它们是不同的概念!


目录
相关文章
|
1月前
|
搜索推荐 Android开发 iOS开发
安卓与iOS系统的用户界面设计对比分析
本文通过对安卓和iOS两大操作系统的用户界面设计进行对比分析,探讨它们在设计理念、交互方式、视觉风格等方面的差异及各自特点,旨在帮助读者更好地理解和评估不同系统的用户体验。
23 1
|
1月前
|
搜索推荐 Android开发 iOS开发
安卓与iOS操作系统的发展与比较
在移动互联网时代,安卓和iOS两大操作系统在智能手机市场竞争激烈。本文将从技术架构、生态系统、用户体验等方面对安卓和iOS进行比较分析,探讨它们各自的特点和发展趋势。
|
1月前
|
Web App开发 前端开发 网络安全
前端分析工具之 Charles 录制 Android/IOS 手机的 https 应用
【2月更文挑战第21天】前端分析工具之 Charles 录制 Android/IOS 手机的 https 应用
58 1
前端分析工具之 Charles 录制 Android/IOS 手机的 https 应用
|
1月前
|
人工智能 算法 Android开发
探索未来:Android与iOS在人工智能时代的融合与创新
【2月更文挑战第13天】 在数字化时代的快速发展下,Android与iOS作为两大主流移动操作系统,它们在人工智能(AI)领域的融合与创新已成为推动科技进步的关键力量。本文将从操作系统的核心功能拓展、AI技术的集成应用,以及开发者生态系统的演变三个维度,深入探讨Android和iOS如何在AI时代实现协同发展,以及这一进程对用户体验、应用开发和行业趋势产生的深远影响。通过对比分析和案例研究,我们旨在揭示两大平台在AI驱动下的创新路径,及其对未来科技格局的塑造作用。
|
1月前
|
人工智能 自然语言处理 语音技术
探索未来:安卓与iOS在人工智能领域的竞争与合作
【2月更文挑战第12天】本文深入探讨了安卓和iOS两大操作系统在人工智能(AI)领域的发展现状、竞争态势及未来合作可能性。通过对比分析两系统在AI技术集成、开发者支持、用户体验优化等方面的表现,揭示了它们各自的优势与挑战。文章最终展望了一个既有竞争又充满合作的未来,认为安卓和iOS的共同进步将推动整个人工智能技术向前发展,为用户带来更加智能、便捷的生活体验。
|
1月前
|
搜索推荐 Android开发 iOS开发
探索未来:安卓与iOS双系统的融合与创新
【2月更文挑战第12天】 在数字化时代,智能手机操作系统的发展不仅代表了技术的进步,更是用户体验革新的前沿。本文深入探讨了安卓和iOS这两大主流操作系统的未来走向,特别是它们在技术融合与创新方面的可能性。通过分析当前的市场需求、技术挑战和潜在的发展机会,我们将展望一个可能出现的未来场景:一个结合了安卓开放性和iOS优雅体验的双系统融合平台。这不仅仅是对技术极限的挑战,更是对用户体验极致追求的一次探索。
37 2
|
1月前
|
人工智能 搜索推荐 Android开发
探索未来:安卓与iOS在人工智能时代的融合趋势
【2月更文挑战第12天】 在这篇探索性文章中,我们将深入分析安卓和iOS两大移动操作系统在人工智能(AI)时代的融合趋势。随着技术的飞速发展,AI已成为推动智能手机进化的关键力量。本文通过对安卓和iOS各自在AI领域的最新进展进行比较,揭示了两大平台如何在保持各自特色的同时,也在向着更加智能、更加个性化的方向发展。我们不仅聚焦于当前的技术现状,而且还将展望未来,探讨这一趋势对用户体验、应用开发以及整个科技生态的深远影响。
|
1月前
|
人工智能 安全 搜索推荐
探索未来:安卓与iOS在人工智能时代的融合与创新
【2月更文挑战第12天】随着人工智能(AI)技术的飞速发展,安卓和iOS系统作为智能手机操作系统的两大巨头,正面临着前所未有的融合与创新机遇。本文将从AI技术对移动操作系统的影响、两大系统在AI领域的创新应用,以及未来可能的融合方向三个方面进行深入探讨。通过对比分析,我们旨在揭示安卓和iOS在人工智能时代如何共同推进技术革新,为用户提供更加智能、便捷的服务体验。
|
1月前
|
机器学习/深度学习 人工智能 算法
探索未来:Android与iOS在人工智能时代的融合与创新
【2月更文挑战第11天】 在数字化浪潮和人工智能技术的加速发展下,Android和iOS两大移动操作系统正面临前所未有的挑战与机遇。本文将深入探讨这两大平台如何在人工智能领域进行融合与创新,以及这些变革对消费者、开发者和整个科技生态的影响。我们将从操作系统的智能化升级、应用生态的变革、用户体验的革新三个方面入手,展望Android和iOS在人工智能时代的未来走向。
|
6天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
24 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库