lua 字符串分割_Lua函数式编程(中)

9ad854ed02b545fe80b7d43360303cc5.png

书接前文,我们继续慢慢的了解 所谓的函数式编程思想。考查下面的例子

判断给定的数是否是偶数

在Lua里面这似乎是个幼儿园问题

local isEven = function(v) return v % 2 == 0 end

但我们如何用函数式的思维去解决问题?是的,假设我们有了以下函数

R.mod -- 求余数
R.equals -- 判断是否相等

我们为何要新造一个函数轮子呢?有什么办法可以重复利用已有的函数算法呢?

函数组合

最强大的函数式编程核武器出现了。这就是函数组合,但是理解这个概念一点都不困难,就像是数学中的函数一样

y = f(x) , z = g(y) = g(f(x))
h = ComposeMagic(f, g) //考虑将f函数和g函数进行组合
z = h(x) //这样可以直接得到最终结果

函数组合就像一个管道一样,假想一组数据要经过f g h三个函数的加工,变成最终我们需要的数据

values -> f() -> g() -> h() -> results

那么中间的函数实际上可以经由compose组合,变成一个函数算法

values -> composed() -> results

这个就是函数组合的思维核心,经由函数自身的逻辑操作,而非针对值的操作,因此可以充分的利用诸多已经实现好的小函数、小算法、小轮子,自由组合而成为我们需求的算法

是时候用函数式思想实现之前的那个算法了

local isEven = R.compose(R.equals(0), R.mod(2))

compose方案会组合后面的函数,使其从后往前依次接收数据、返回处理结果。

number -> R.mod(2) 求得余数 -> 返回结果 -> R.equals(0) 判断是否与0相等 -> 返回结果

不过这对于这个算法来说确实大材小用了,但是这其中的思想还是值得我们研习的。来看个复杂点的例子

实现一个算法,将IP4的地址转换为一个Int32的数

我们先看传统的实现(其中仍然借助了R.split方法,我们就当成一个传统方法来使用)

local function convertIp2Int(ip)local ip_numbers = R.split(".", ip)local result = 0local offset = 1for i, ipn in ipairs(ip_numbers) doresult = result + tonumber(ipn) * offsetoffset = offset * 256endreturn result
end

这个实现的确不怎么好看,而且还要注意他的约定是 big-endian,如果修改成little-endian,我们得钻到函数细节里面去想办法。

让我们体会下函数组合的强大吧。先看看最终实现

local split = R.split(".")
local parse = R.map(tonumber)
local offset = function(f, s) return f * 256 + s end
local convertIp2Int = R.compose(R.reduce(offset, 0), parse, R.reverse, split)

如果想实现little-endian版本的,只需要移除组合函数中的R.reverse方法即可,基于原题目,我们可以简化一下

local offset = function(f, s) return f * 256 + s end
local convertIp2Int = R.compose(R.reduce(offset, 0), R.map(tonumber), R.split('.'))

数据流向如下

"192.168.1.1"             -> R.split('.') 分割字符串 ->
{"192","168","1","1"}     -> R.map(tonumber) 对列表中的每个元素进行tonumber转换 ->
{192, 168, 1, 1}          -> R.reduce(offset, 0) 每两个元素执行一次offset操作,将列表合并为一个Int32数字
-> 3232235777

而且欣慰的是,过程中的中间函数,都可以作为其他算法的子函数继续组合使用,函数组合充分的解放了对造轮子的冲动,这就是函数编程思想的核心魅力。

副作用(Side Effect)和不可变(Immutable)

什么是函数?经典的Pascal语言有两个关键字,很好的区分了函数和过程

function --> 给定输入,经过函数算法,返回给定的输出;相同的输入永远返回相同的输出,没有副作用。
procedure --> 给定输入,经过过程算法,改变某些状态,有副作用。

在函数式编程思维中,function必须的纯净的,无副作用的,其特性为

  1. 不依赖全局变量
  2. 不修改函数参数
  3. 不修改任何状态(db、io、网络、标准输出、对象等等)
  4. 只要输入一样,输出必定一样

这些特性使得函数具有了非常诱人的特性

  1. 可测试性(只需要给定参数就能判定这个函数是否工作正常,不需要Mock任何对象系统)
  2. 可缓存性(只要参数一样,就返回一样的内容,很容易缓存算法结果)
  3. 可并发性(没有副作用,没任何数据竞争,多线程跑跑算法,安全的很)
  4. 自解释性(描述参数和返回值即可,不用考虑任何外部系统知识)
  5. 引用透明(可以在算法中将函数调用替换为他的结果)

但是很遗憾,本文无法做深入展开(您可以参考任何一篇介绍函数式编程思想的文章)

纯净的函数使得传入的参数被安全的保护起来,你不希望你的列表传入一个算法,然后被这个算法破坏的乱七八糟吧。

local list = {1,2,3}
R.append(4, list) --> list 仍然是1,2,3 这种保障去掉了相当多对引用做修改而导致的Bug

下一篇我们会就性能、函数签名做一番探讨,有兴趣的可以继续关注。

谢谢阅读。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/397879.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序)...

WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序) 原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序)基于HTTP-GET的元数据发布方式与基于WS-MEX原理类似…

)标识符不能是c语言的关键字,标识符不能是C的关键字

满意答案tftgcl882014.08.07采纳率:58% 等级:9已帮助:3967人所谓关键字就是已被Turbo C2.0本身使用, 不能作其它用途使用的字。例如关键字不能用作变量名、函数名等。Turbo C2.0有以下关键字:Turbo C2.0扩展的共11个asm …

不同类的方法 事务问题_【高中地理】描述类问题的答题方法

一、描述地理位置的特征及意义位置:半球位置、纬度位置、海陆位置、相对位置(邻省或邻国、地形区、地势阶梯交界处、气候区、图例中的特殊地理事物)、板块位置、交通位置等。意义:①所处位置(是否是重要分界线&#xf…

Debian 系统安装 Nagios 服务器监控端

安装apt-get updateapt-get install nagios* perlapt-get install --no-install-recommends pnp4nagiosapt-get install apache2 apache2-utils php5 php-pear 修改npcd设置# vim /etc/default/npcdRun"yes"# service npcd start 添加process_perfdata.pl执行权限ch…

spark-stream 访问 Redis

最近在spark-stream上写了一些流计算处理程序,程序架构如下 程序运行在Spark-stream上,我的目标是kafka、Redis的参数都支持在启动时指定。 在写代码时参考了这篇文章 https://www.iteblog.com/archi...,该文讲的比较清楚,但是有两…

东软睿云用户认证_【硬件资讯】尘埃落定!11代酷睿规格曝光!i7、i9难分差距,退回8核16线程!...

新闻①:Intel第11代酷睿处理器规格曝光,旗舰i9-11900K与i7-11700K同为8核16线程Intel的代号为Rocket Lake-S的第11代酷睿台式机CPU阵容将于明年推出,其中四个型号的规格现已曝光。拥有8个Cypress Cove核心、5.3GHz、PL2功耗限制250W的酷睿i9-…

环上的游戏

环上的游戏(cycle)有一个取数的游戏。初始时,给出一个环,环上的每条边上都有一个非负整数。这些整数中至少有一个0。然后,将一枚硬币放在环上的一个节点上。两个玩家就是以这个放硬币的节点为起点开始这个游戏&#xf…

python基础课程_2学习笔记3:图形用户界面

图形用户界面 丰富的平台 写作Python GUI程序前,须要决定使用哪个GUI平台。 简单来说,平台是图形组件的一个特定集合。能够通过叫做GUI工具包的给定Python模块进行訪问。工具包 描写叙述 Tkinter 使用Tk平台。非常easy得到。半标准。 wxpython 基于…

idea ssm打war包_IDEA下从零开始搭建SpringBoot工程

SpringBoot的具体介绍可以参看其他网上介绍,这里就不多说了,就这几天的学习,个人理解,简而言之:如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友…

dataframe 众数的方法_学习数据分析数据方法论 [描述性统计分析]

数理统计:数理统计是以概率论为基础,研究社会和自然界中大量随机现象数量变化基本规律的一种方法。分为:描述统计(描述统计的任务是搜集资料,进行整理、分组,编制次数分配表,绘制次数分配曲线,计…

c语言高级语言期中测试答案,上海理工大学C语言2011期中试题和答案

C语言2010/2011学年 第二学期 期中测试高级语言程序设计(C)试卷 A □BA1. 输入一行字符&#xff0c;统计其中的英文字母个数。#include void main(){ char ch;int n0;printf(“Input a string:\n”);while(1){ chgetchar();if (ch \n ) break;if (ch> a && ch< z…

如何构建ASP.NET MVC4JQueryAJaxJSon示例

背景&#xff1a; 博客中将构建一个小示例&#xff0c;用于演示在ASP.NET MVC4项目中&#xff0c;如何使用JQuery Ajax。 直接查看JSon部分 步骤&#xff1a; 1&#xff0c;添加控制器(HomeController)和动作方法(Index),并为Index动作方法添加视图(Index.cshtml),视图中HTML如…

echarts 有引导线和内部文字_点、线、面构图的异同以及相互转化

点、线、面构图既有相似性&#xff0c;又有差异性。相似的是都有对齐、强调、群组、重复、突出层次的作用&#xff0c;不同的是点的特点是聚焦、线的特点是运动和方向性&#xff0c;面的特性是体量感、稳定性。点的情感最弱&#xff0c;线、面的情感要比点丰富。一、点、线、面…

《Python黑帽子:黑客与渗透测试编程之道》 Web攻击

Web的套接字函数库&#xff1a;urllib2 一开始以urllib2.py命名脚本&#xff0c;在Sublime Text中运行会出错&#xff0c;纠错后发现是重名了&#xff0c;改过来就好&#xff1a; #!/usr/bin/python #codingutf-8 import urllib2url "http://www.baidu.com"headers …

vCenter Converter Standalone使用文档

文档目的能够使用vCenter Converter Standalone 将物理机操作系统迁移到虚拟机操作系统基础知识vCenter Converter Standalone 能将物理机上的操作系统、VMware虚拟机上的操作系统或者Hype-V 上的虚拟机操作系统迁移到VMware上。系统环境操作系统&#xff1a;Windows Server 20…

1093芯片做正弦波逆变器_正弦波逆变器中的SPWM调制(钟任生)

欢迎加入技术交流QQ群(2000人)&#xff1a;电力电子技术与新能源 905723370高可靠新能源行业顶尖自媒体在这里有电力电子、新能源干货、行业发展趋势分析、最新产品介绍、众多技术达人与您分享经验&#xff0c;欢迎关注我们&#xff0c;搜索微信公众号&#xff1a;电力电子技术…

android 手机短信恢复,安卓手机短信删除了怎么恢复?简单恢复的方法

原标题&#xff1a;安卓手机短信删除了怎么恢复&#xff1f;简单恢复的方法安卓手机短信删除了怎么恢复&#xff1f;手机短信是生活中不经常使用到&#xff0c;但是依然是十分重要的存在&#xff0c;因为我们现在比较喜欢用社交软件与别人进行交流&#xff0c;但是在一些相对重…

bash下个人习惯的一些文件设置

2019独角兽企业重金招聘Python工程师标准>>> bash_profile export PATH/usr/local/bin:$PATH export EDITORviinputrc set editing-mode vi #set editing-mode emacs set show-all-if-ambiguous on set completion-ignore-case on set meta-flag on set conver…

docker打包镜像上传_Jenkins | 一键打包部署Spring Boot 应用的Docker镜像

一、前言1、本文主要内容将在项目中实际使用到的相关东西整理记录一波&#xff0c;同时可以方便其他同学在使用到的时候参考一下(自己也备忘)&#xff0c;有不对的地方&#xff0c;欢迎指出~~Docker部署SpringBoot 项目通用Dockerfile文件、脚本Jenkins新建任务图文详解3、本文…

android 发送短信 广播 demo,向Android模拟器打电话发短信的简单方法

在开发android应用程序时&#xff0c;有时候需要测试一下向android手机拨打电话发送短信时该应用程序的反应。譬如编写一个广播接收器&#xff0c;来提示用户有短信收到或者处理短信&#xff0c;就需要向该手机发送短信来进行测试。这里介绍一种简单的向android模拟器打电话发短…