最近接触到一个函数叫ets:fun2ms/1,因为不了解被坑了,来解析下他的用法和常用情景

基本含义

把语法函数转为匹配规范的伪函数,听到这个可能就蒙了,有啥用啊

fun2ms(LiteralFun) -> MatchSpec

使用一个解析转换的仿函数 ListeralFun 作为参数传递给该函数转换出一个匹配规范。“literal” 意味着函数必须以的文本的形式作为函数的参数,它不能是依次传递给函数的变量。

需要注意的是,使用这个fun2ms的函数必须在代码文件前面加入这一行,

-include_lib("stdlib/include/ms_transform.hrl").

否则会报这个错,我当时就找了半天bug

加了的话就会编译正常

示例

2> ets:fun2ms(fun({M, N}) when N > 3 -> M end).
[{{'$1','$2'},[{'>','$2',3}],['$1']}]
这里可以看到函数返回的是一个匹配规范,第一个参数第二个参数,大于号、第二个参数、具体的3,返回第一个参数3> X = 3,
ets:fun2ms(fun({M, N}) when N > X -> M end).
[{{'$1','$2'},[{'>','$2',{const,3}}],['$1']}]
也可以用外部变量,const就是全局常量4> ets:fun2ms(fun({M, N}) when N > 3, is_atomm(M) -> M end).
* 1: illegal guard expression
这里就报错了,因为局部函数或全局函数是不能出现在函数的断言里的5> ets:fun2ms(fun({M, N}) when N > 3, is_atom(M) -> M end).
[{{'$1','$2'},[{'>','$2',3},{is_atom,'$1'}],['$1']}]
内置函数可以被匹配规范函数调用

延伸

这里的4、5行里when后面有一种可以一种不可以,这个在之前我有个朋友出现了类似的问题并且和我请教,当时印象有点深,因为这个点我也很模糊。when后面不能接自己写的函数,但是内置的函数可以做条件

比如:

这里用了内建函数,但是编译的时候不能知道结果所以也不行,可以发现下面的代码在IDEA里敲完就直接报错了

导师的解释是when在匹配后面必须要有确定的结果,编译的时候就能知道结果的运算或者是NIF(Native Implemented Function)的。

NIF补充知识

在Erlang中,NIF(Native Implemented Function)被用来扩展erlang的某些功能,一般用来实现一些erlang很难实现的,或者一些erlang实现效率不高的功能。

NIF使用C开发,效率和C接近,比纯erlang实现要高。NIF会编译成动态库,直接动态加载到erlang进程空间调用,也是erlang扩展新方法最高效的做法。调用NIF不用上下文的切换开销,但是也有代价,NIF的crash会导致整个Erlang进程crash。

我的理解是与NIF对立的就是我们熟悉的BIFs(Build-in Functions)内建函数,内建函数就是比如trunc直接erlang:trunc就可以调用的,常见的内建函数:

函数名 功能 函数名 功能
trunc 取整数部分 round 四舍五入
float 转化为浮点数 is_atom 判断是否为原子
is_tuple 判断是否为元组 hd/1 返回列表的第一个元素
tl/1 返回列表的最后一个元素 length/1 返回列表的长度
tuple_size/1 返回元组大小 element/1 返回第n个元组的元素
函数名 功能
setelement/3 替换元组中的某一个元素,并返回新元组,setelement(要替换原子的位置,元组名,新原子的值)
erlang:append_element/2 添加一个原子到元组的末尾。(元组名,新原子的值)
类型转换
atom_to_list 原子转化为列表->字符串
list_to_atom 列表转化为原子
integer_to_list 整数转化为列表
list_to_tuple tuple_to_list
float,list_to_float float_to_list,integer_to_list

那这里后面到底可以写什么?

  • 判断数据类型(内建函数):is_binary, is_atom, is_boolean, is_tuple
  • 比较运算符:==, =/=, <, >…
  • 判断语句: not, and, xor…

可以发现没报错的

可以发现复杂点的还是会报错

回到fun2ms使用用法

和select搭配

我们发现ets:select/2中的参数为select(Tab, MatchSpec) -> [Match],这里第二个参数可不就是咱fun2ms的返回值吗,

这不冲他

示例

1> ets:new(tab,[set,named_table]).
tab
2> ets:insert(tab,[{apple,1},{banana,2},{orange,3}]).
true
3> ets:fun2ms(fun({Key, Value} = Object) when Key =:= apple -> Object end).
[{{'$1','$2'},[{'=:=','$1',apple}],['$_']}]
4> Ms = ets:fun2ms(fun({Key, Value} = Object) when Key =:= apple -> Object end).
[{{'$1','$2'},[{'=:=','$1',apple}],['$_']}]
5> ets:select(tab, Ms).
[{apple,1}]
6>

我对这个fun2ms的返回值的理解是,提前给条件做一个判断,这里就是先设置Key=apple的类型的,然后匹配Key、Value类型来做判断,再作为select第二个参数传入,发现确实能匹配出对应Key==apple类型的

和match_spec_compile搭配

反正冷门了,不怕再冷门点,我们查API发现ets:match_spec_compile/1这个函数,传入的参数也是MatchSpec,咋说,试下呗

match_spec_compile(MatchSpec) -> CompiledMatchSpec

测试发现返回一个不认识的东西

1> MatchSpec = ets:fun2ms(fun({M, N}) when N > 3 -> M end),
ets:match_spec_compile(MatchSpec).
#Ref<0.1118727578.437125123.105226>

查表解释为这个函数将一个匹配规范MatchSpec转换为一个可用于ets:match_sprc_run/2在后续调用的内部表示形式。转换后的内部形式“不透明”的一个数据,并不能转回为其原来的外部数据格式,并且完好无损的转回。

示例

1> MatchSpec = ets:fun2ms(fun({M, N}) when N > 3 -> M end),
CompileMatchSpec = ets:match_spec_compile(MatchSpec).
#Ref<0.2741862248.2048524291.40502>
2> List = [{1,2},{3,4},{5,6}].
[{1,2},{3,4},{5,6}]
3> ets:match_spec_run(List,CompileMatchSpec).
[3,5]
4>

越兜越复杂了哈,先看懂吧~

和is_compile_ms的搭配

还有个一起说下吧,这个函数主要是检查已编译的匹配描述是否是有效的,

is_compiled_ms(Term) -> boolean()

示例

1> MatchSpec = ets:fun2ms(fun({M, N}) when N > 3 -> M end).
[{{'$1','$2'},[{'>','$2',3}],['$1']}]
2> Term = ets:match_spec_compile(MatchSpec).
#Ref<0.63853007.1514536963.50818>
3> ets:is_compiled_ms(Term).
true
4> ets:is_compiled_ms(MatchSpec).
false
5>

可以看到只有符合要求的返回true,其他任意类型均返回false

Erlang_ets冷门函数fun2ms相关推荐

  1. PHP中的pack和unpack函数

    转载请注明文章出处:https://tlanyan.me/php-pack-a... PHP有两个重要的冷门函数:pack和unpack.在网络编程,读写图像文件等场景,这两个函数几乎必不可少.鉴于文 ...

  2. 函数周期表丨信息丨值丨ISONORAFTER

    ISONORAFTER函数 ISONORAFTER函数隶属于"信息"类函数.这个函数的出场率并不是特别高,其效果类似于Start At的行为,属于冷门函数之一. 用途:可以用来划定 ...

  3. 求最大值_Excel求最大值地球人都知道,那要求出第2、第3、第N大值呢?

    只要稍稍懂点excel的人,都会轻松地求出最大值.最小值. 那要求出第2大值.第3大值--第N大值呢? 往下看,掌握了方法,排序又变得很简单了. 最大最小值 最大值:=max(B:B),最小值:=mi ...

  4. 黑客是如何绕过WAF的

    1.什么是WAF Web Application Firewall 通过执行一系列针对HTTP/HTTPS的安全策略来防御对Web应用的攻击. 目前主要有单设备WAF与云WAF 2.WAF的现状 1. ...

  5. WAF机制及绕过方法总结:注入篇

    本篇文章主要介绍WAF的一些基本原理,总结常见的SQL注入Bypass WAF技巧.WAF是专门为保护基于Web应用程序而设计的,我们研究WAF绕过的目的一是帮助安服人员了解渗透测试中的测试技巧,而是 ...

  6. 汇编语言 把最大值放入max 把最小值放入min_Excel求最大值地球人都知道,那要求出第2、第3、第N大值呢?...

    只要稍稍懂点excel的人,都会轻松地求出最大值.最小值. 那要求出第2大值.第3大值--第N大值呢? 往下看,掌握了方法,排序又变得很简单了. 最大最小值 最大值:=max(B:B),最小值:=mi ...

  7. Bypass部分知识

    Bypass部分知识 Upload: 容器特性: Apache1.X/2.X  从后向前识别,直到可识别的扩展名  x.php.asd IIS6  目录为*.asp/*.asa等可被IIS动态执行的扩 ...

  8. 【R】【决策树】【随机森林】

    文章目录 实验思维导图 1.决策树--ctree()--iris 1.1 数据 1.1.1 程序包加载 1.1.2 数据集探索 1.1.3 数据集拆分 1.2 训练 1.2.1 设置因变量.自变量 1 ...

  9. 0day安全:软件漏洞分析技术——系统内核漏洞

    本文是阅读<0day安全:软件漏洞分析技术>后的笔记.      内核漏洞主要的作用包括:远程任意代码执行,本地权限提升,远程拒绝服务攻击,本地拒绝服务攻击.从漏洞的利用来看,远程拒绝服务 ...

  10. 【C语言】计算器(支持括号和长式子)

    目标:输入像(1+2*(3-4))/5+6=这样的计算式,程序可以识别并且得出最终结果. 思路:将计算式子存在一个数组里,然后进行有限次化简直至得出最简形式(一个值).要化简的形式分为两种: 长式子的 ...

最新文章

  1. 身份证号信息后台匹配
  2. 【 Linux 】安装、配置并用 Vim 编写第一个 C 程序
  3. 如何将Windows Server域(AD活动目录)中的用户导出并导入至Outlook2010通讯簿
  4. 微软职位内部推荐-Principal Software Developer
  5. 把程序显示在最前面 delphi_地球程序员之神:没上过大学,曾拒盖茨的Offer,4代码农靠他吃饭...
  6. apache 统计404日志_Apache监控与调优(四)Apachetop监控
  7. java servlet 执行 多次_servlet 验证生命周期过程调用方法的次数
  8. 基于django的视频点播网站开发-step12-后台订阅功能...
  9. 【LeetCode】【字符串】题号:*557. 反转字符串中的单词 III
  10. html引入苹方字体,原 前端项目,引入苹方字体
  11. 计算机硬件基础与计算机组装知识总结
  12. Android音频的录制与播放
  13. jpa blob mysql_Spring让BLOB 和Clob数据操作变得简单易行
  14. Spring:applicationContext.xml的头文件信息
  15. python抓取A股市场历史数据(个股、指数)
  16. 数据库-MySQL-基础(2)-DDL操作
  17. 分享65个NET源码,总有一款适合您
  18. 基于ROS节点实现USB camera在web显示
  19. 略论错误提示的人性化
  20. 广工软件工程第一次作业

热门文章

  1. 2021年茶艺师(中级)复审考试及茶艺师(中级)模拟考试题
  2. QCC305x系列开发教程(入门篇)之1.3-烧录方式使用USB时的驱动安装及其出现“未知设备”的解决方法
  3. ThinkpadX230解决叹号_Win7系统设备管理器下的“未知设备”
  4. css mix-blend,CSS混合模式mix-blend-mode/background-blend-mode简介
  5. 怎么彻底删除users下的文件夹_什么工具可以有效清理C:\Users\用户名\AppData目录下的文件?...
  6. 【最新】白piao迅雷的下载速度(迅雷11亲测好用)
  7. Pytorch grid_sample解析
  8. 百胜中国拟2025年前开1000家Lavazza咖啡店​;别样肉客开始陆续进驻中国山姆会员商店 | 知消...
  9. CentOS 7系统上制作Clonezilla(再生龙)启动U盘并克隆双系统
  10. Xposed插件 - Android一键脱壳工具