热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关键字列表有什么好处?

如何解决《关键字列表有什么好处?》经验,为你挑选了2个好方法。

在灵丹妙药中我们有地图:

> map = %{:a => "one", :b => "two"} # = %{a: "one", b: "two"}
> map.a                             # = "one"
> map[:a]                           # = "one"

我们还有关键字列表:

> kl = [a: "one", b: "two"]       # = [a: "one", b: "two"]
> kl2 = [{:a, "one"},{:b, "two"}] # = [a: "one", b: "two"]
> kl == kl2                       # = true
> kl[:a]                          # = "one"
> kl.a                            # = ** (ArgumentError)

两个为什么?

句法?是因为关键字列表具有更灵活的语法,允许它们被定义为没有卷曲,甚至没有括号作为函数调用的最后一个参数?那为什么不给这个语法糖吗?

重复密钥?是因为关键字列表可以有重复的键吗?为什么要同时使用Map样式访问和重复键?

性能?是因为关键字列表有更好的表现吗?那为什么要有地图?并且不应该通过键查找成员比使用元组列表更高效吗?

JS Array和Ruby Hash一样外观?是吗?

我理解结构上它们是不同的数据表示.对我而言,似乎elixir中的关键字列表通过特殊语法(3种不同的句法变体),用例与地图重叠以及不明确的好处使语言复杂化.

使用关键字列表有什么好处?



1> Patrick Osci..:
                   ?????????????????????????????????????????????????????
                   ? Keyword List ? Map/Struct ? HashDict (deprecated) ?
????????????????????????????????????????????????????????????????????????
? Duplicate keys   ? yes          ? no         ? no                    ?
? Ordered          ? yes          ? no         ? no                    ?
? Pattern matching ? yes          ? yes        ? no                    ?
? Performance¹     ? —            ? —          ? —                     ?
? ? Insert         ? very fast²   ? fast³      ? fast?                 ?
? ? Access         ? slow?        ? fast³      ? fast?                 ?
????????????????????????????????????????????????????????????????????????

关键字列表是轻量级的,在它们下面有一个简单的结构,这使它们非常灵活.您可以将它们视为基于Erlang约定的语法糖,使得在不编写过于丑陋的代码的情况下轻松与Erlang进行交互.例如,关键字列表用于表示函数参数,这是从Erlang继承的属性.在某些情况下,关键字列表是您唯一的选择,特别是如果您需要重复键或订购.它们具有与其他替代品不同的特性,这使得它们更适合某些情况而不适合其他情况.

Maps(和Structs)用于存储实际的有效负载数据,因为它们具有基于散列的实现.内部的关键字列表只是每个操作需要遍历的列表,因此它们不具有经典键值数据结构的属性,如常量时间访问.

Elixir还介绍HashDict了在编写地图时地图表现不佳的解决方法.但是,现在从Elixir 1.0.5/Erlang 18.0开始修复HashDict ,将来的版本将不推荐使用.

如果深入研究Erlang标准库,还有更多存储键/值对的数据结构:

proplists - 类似于Elixir关键字列表

地图 - 与Elixir地图相同

dict - 从Erlang原语构建的键值字典

gb_trees - 一般平衡树

当您需要跨多个进程和/或VM存储键/值对时,您还可以使用以下选项:

ets/dets - (基于磁盘)Erlang术语存储

mnesia - 分布式数据库


¹一般来说,但当然取决于 ™.

²最好的情况只是在列表前面.

³适用于Elixir 1.0.5及更高版本,在旧版本中可能会更慢.

HashDict现在被弃用了.

⁵需要线性搜索,平均扫描一半的元素.


@greggreg使用关键字列表还有另一个隐含的好处:我们对结构化和非结构化数据进行区分.地图对于具有已知密钥集的结构化数据非常有用,而关键字则不是.今天,大多数地图用于结构化数据,我们为可选数据留下关键字.如果我们只有地图,我认为这种区别的很大一部分将会丢失.
严格来说,是的,但如果您需要这些属性,它们可能会带来好处 - 这就是我的意思.

2> Voldy..:

关键字列表的主要好处是与现有的elixir和erlang代码库向后兼容.

如果用作函数参数,它们也会添加语法糖,类似于ruby语法:

def some_fun(arg, opts \\ []), do: ...
some_fun arg, opt1: 1, opt2: 2

使用关键字列表的主要缺点是无法对它们执行部分模式匹配:

iex(1)> m = %{a: 1, b: 2}
%{a: 1, b: 2}
iex(2)> %{a: a} = m
%{a: 1, b: 2}
iex(3)> a
1
iex(4)> k = [a: 1, b: 2]
[a: 1, b: 2]
iex(5)> [a: a] = k
** (MatchError) no match of right hand side value: [a: 1, b: 2]

让我们将它扩展为函数参数.想象一下,我们需要根据其中一个选项的值来处理多重函数:

def fun1(arg, opt1: opt1) when is_nil(opt1), do: do_special_thing
def fun1(arg, opts), do: do_regular_thing

def fun2(arg, %{opt1: opt1}) when is_nil(opt1), do: do_special_thing
def fun2(arg, opts), do: do_regular_thing

这永远不会执行do_special_thing:

fun1("arg", opt1: nil, opt2: "some value")
doing regular thing  

使用map参数,它将起作用:

fun2("arg", %{opt1: nil, opt2: "some value"})
doing special thing


推荐阅读
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • 本文介绍了如何使用python从列表中删除所有的零,并将结果以列表形式输出,同时提供了示例格式。 ... [详细]
  • 006_Redis的List数据类型
    1.List类型是一个链表结构的集合,主要功能有push,pop,获取元素等。List类型是一个双端链表的结构,我们可以通过相关操作进行集合的头部或者尾部添加删除元素,List的设 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • Day2列表、字典、集合操作详解
    本文详细介绍了列表、字典、集合的操作方法,包括定义列表、访问列表元素、字符串操作、字典操作、集合操作、文件操作、字符编码与转码等内容。内容详实,适合初学者参考。 ... [详细]
  • Java程序设计第4周学习总结及注释应用的开发笔记
    本文由编程笔记#小编为大家整理,主要介绍了201521123087《Java程序设计》第4周学习总结相关的知识,包括注释的应用和使用类的注释与方法的注释进行注释的方法,并在Eclipse中查看。摘要内容大约为150字,提供了一定的参考价值。 ... [详细]
  • Java学习笔记之使用反射+泛型构建通用DAO
    本文介绍了使用反射和泛型构建通用DAO的方法,通过减少代码冗余度来提高开发效率。通过示例说明了如何使用反射和泛型来实现对不同表的相同操作,从而避免重复编写相似的代码。该方法可以在Java学习中起到较大的帮助作用。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • Ihaveaworkfolderdirectory.我有一个工作文件夹目录。holderDir.glob(*)>holder[ProjectOne, ... [详细]
  • HashMap的扩容知识详解
    本文详细介绍了HashMap的扩容知识,包括扩容的概述、扩容条件以及1.7版本中的扩容方法。通过学习本文,读者可以全面了解HashMap的扩容机制,提升对HashMap的理解和应用能力。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
author-avatar
许心怡917
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有