Scala 中的右关联方法有什么好处?

2023-12-06

我刚刚开始使用 Scala,并且刚刚了解了如何创建方法右结合(与更传统的左结合性在命令式面向对象语言中很常见)。

起初,当我看到示例代码时consScala 中的列表,我注意到每个示例总是在右侧有列表:

println(1 :: List(2, 3, 4))
newList = 42 :: originalList

然而,即使一遍又一遍地看到这个,我也没有多想,因为我(当时)不知道::是一个方法List。我只是假设它是一个运算符(同样是 Java 中运算符的意义),并且关联性并不重要。事实是List总是出现在示例代码的右侧似乎很巧合(我认为这可能只是“首选样式”)。

现在我更清楚了:它必须这样写,因为::是右结合的。

我的问题是,能够定义右关联方法有什么意义?

纯粹是出于审美原因,还是在某些情况下右关联实际上比左关联有某种好处?

从我(新手)的角度来看,我真的不明白如何

1 :: myList

比什么更好

myList :: 1

但这显然是一个微不足道的例子,我怀疑这是一个公平的比较。


简而言之,右关联性可以通过使程序员键入的内容与程序实际执行的内容一致来提高可读性。
所以,如果你输入 '1 :: 2 :: 3',你会得到一个 List(1, 2, 3) 返回,而不是以完全不同的顺序返回一个 List。
那是因为'1 :: 2 :: 3 :: Nil' 实际上是

List[Int].3.prepend(2).prepend(1)

scala> 1 :: 2 :: 3:: Nil
res0: List[Int] = List(1, 2, 3)

这是两者:

  • 更具可读性
  • 更高效(O(1) 为prepend,与假设的 O(n) 相比append method)

(温馨提示,摘自书中Scala 编程)
如果一个方法用在运算符表示法中,例如a * b,该方法在左侧操作数上调用,如下所示a.*(b)— 除非方法名称以冒号结尾。
如果方法名称以冒号结尾,则在右侧操作数上调用该方法。
因此,在1 :: twoThree, the ::方法被调用于twoThree,传入 1,如下所示:twoThree.::(1).

对于List来说,它起到了追加操作的作用(列表好像是追加在‘1’后面,形成‘1 2 3',实际上它是 1前置的到列表)。
类 List 不提供真正的追加操作,因为追加到列表所需的时间随着列表的大小线性增长,而前面加上 :: 需要恒定的时间.
myList :: 1会尝试将 myList 的整个内容添加到“1”,这比将 1 添加到 myList 更长(如“1 :: myList')

注意:无论运算符具有何种结合性,其操作数都是 总是从左到右评估。
因此,如果 b 是一个表达式,不仅仅是对不可变值的简单引用,那么 a ::: b 更准确地被视为以下块:

{ val x = a; b.:::(x) }

在这个块中,a仍然先于b进行评估,然后是本次评估的结果 作为操作数传递给 b 的 ::: 方法。


为什么要区分左联想和右联想方法呢?

这允许保持通常的左关联操作的外观('1 :: myList') 在实际对正确的表达式应用操作时,因为;

  • 它更有效率。
  • 但使用逆关联顺序('1 :: myList' vs. 'myList.prepend(1)')

据我所知,正如你所说,“语法糖”。
请注意,在以下情况下foldLeft,例如,他们可能有有点远了(与 '/:' 右结合运算符等价)


为了包含您的一些评论,稍微改写一下:

如果你考虑一个“追加”函数,左关联,那么你会写“oneTwo append 3 append 4 append 5'.
但是,如果将 3、4 和 5 附加到 oneTwo(您可以按照其编写方式进行假设),则复杂度为 O(N)。
如果用于“追加”,则与“::”相同。但事实并非如此。它实际上是为了“前置”

这意味着'a :: b :: Nil'是为了'List[].b.prepend(a)'

如果 '::' 放在前面但仍保持左关联,则结果列表的顺序将是错误的。
您希望它返回 List(1, 2, 3, 4, 5),但最终会返回 List(5, 4, 3, 1, 2),这可能是程序员意想不到的。
那是因为,您所做的按照左关联顺序应该是:

(1,2).prepend(3).prepend(4).prepend(5) : (5,4,3,1,2)

因此,右关联性使代码与返回值的实际顺序相匹配。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala 中的右关联方法有什么好处? 的相关文章

  • 对列表中的相邻元素进行分组

    假设我想编写一个函数来执行此操作 输入 1 1 3 3 4 2 2 5 6 6 输出 1 1 3 3 4 2 2 5 6 6 它将相同的相邻元素分组 这个方法的名称应该是什么 此操作有标准名称吗 In 1 1 3 3 4 2 2 5 6 6
  • 如何使用 `ProjectRef` 来引用 sbt 1.x 中的本地项目?

    其他答案中有很多含糊不清的内容 或者涉及到更旧版本的 sbt 即 0 12 x 但似乎没有人真正回答这个问题 鉴于我有一个文件夹 并且我已经运行 sbt new scala scala seed g8 name Scala Seed Pro
  • 为什么我不能将 Scala 的 Function1 隐式转换为 java.util.function.Function?

    我正在尝试创建 Scala Function1 到 java util function Function 的隐式转换 这是我的代码 object Java8ToScala extends App implicit def javaFunc
  • 赋值运算符左/右侧的不同切片行为

    作为一个来自 C 背景的 Python 新手 Python 3 4 x 中的切片运算符对我来说看起来很荒谬 我只是不明白 特殊规则 背后的设计理念 让我解释一下为什么我说它 特别 一方面 根据 Stack Overflow 的回答here
  • Scala 'null' 是否算作另一种类型的实例?

    我有这个代码 class MyLinkedList T h T tail MyLinkedList T def prepend v T MyLinkedList T new MyLinkedList v this 我想知道我如何可以将第二个
  • 在 Spark 中将流式 XML 转换为 JSON

    我是 Spark 新手 正在开发一个简单的应用程序 将从 Kafka 接收的 XML 流转换为 JSON 格式 Using 火花2 4 5 斯卡拉 2 11 12 在我的用例中 kafka 流采用 xml 格式 以下是我尝试过的代码 val
  • akka-http:找不到参数解组的隐式值

    我的 Spray json 支持看起来像这样 object MarshallingSupport extends SprayJsonSupport implicit def json4sFormats Formats DefaultForm
  • 创建自定义 scala 集合,其中映射默认返回自定义集合?

    特质TraversableLike A Repr 允许人们在其中进行收藏some函数将返回一个Repr 而其他人则继续返回类型参数That在功能上 有没有办法定义一个CustomCollection A 其中函数如map 其他的默认That
  • 错误:无法在 scala 中找到或加载主类

    安装 eclipse scala 插件和 eclipse maven scala 插件后 我是 scala 新手 所以我尝试确保在测试 scala hello world 项目后环境正常工作 它按预期工作 但我在尝试执行我从公司存储库中签出
  • Build.scala中%和%%符号含义

    我是新来玩的 Framework 2 1 java版本 并且没有scala经验 我不明白什么是以及什么是 and 在 Build scala 中表示 我用谷歌搜索了它们但找不到它们的含义 在我的 Build scala 文件中 我有 org
  • 按元素聚合数组

    Spark scala 相当新 我想知道是否有一种简单的方法以按列方式聚合 Array Double 这是一个例子 c1 c2 c3 1 1 1 0 1 0 3 4 1 2 1 0 0 0 4 3 2 1 0 0 0 0 0 0 2 3 1
  • Scala 匿名函数中的 return 语句

    为什么显式 return 语句 使用return关键字 在匿名函数中从封闭的命名函数返回 而不仅仅是从匿名函数本身返回 例如 以下程序会导致类型错误 def foo String x Integer gt return x foo 我知道建
  • WSClient - 打开的文件太多

    我正在 CentOS 6 上使用 Play Framework 2 4 我的应用程序抛出此异常 java net SocketException Too many open files 我在 Stack Overflow 上搜索了很多主题并
  • Jack(Java Android 编译器套件)将如何影响 Scala 开发人员

    现在随着公告Jack https source android com source jack html谷歌阐明了 Java 与 Android 相关的可预见的未来 但这对 Scala 和其他基于 JVM 的语言开发人员有何影响 尤其 Sc
  • xsbt 插件 1.0.0-M7 和 scalatra

    我尝试在我的 scalatra 项目中将 xsbt 插件升级到 1 0 0 M7 但 scalatra 似乎与此版本不兼容 当我尝试重新加载项目时 出现以下错误 我尝试过 scalatra 2 3 0 版本 问候 德斯 java lang
  • Akka中有轻量级的actor吗?

    我的用例非常简单 在两个对象之间交换少量 现在我正在从 Scala Actors 迁移到 Akka 但是我再也找不到那些轻量级 Actors 使用Akka 我不仅需要为Actor创建创建ActorSystem Props 还需要照顾Acto
  • 比较 javascript 元素和 scala 变量的 Play 框架 Twirl 模板

    如下面的代码示例所示 我想比较 scala 辅助元素内的 javascript 元素 然而 即使存在元素 abcde 它也始终返回 false 除了使用标签之外 如何获取 scala 辅助元素内的 javascript 值 appSeq S
  • lambda 演算中的按值调用

    我正在努力克服类型和编程语言 http www cis upenn edu bcpierce tapl 皮尔斯对于按值缩减策略调用 给出了术语的示例id id z id z 内部氧化还原id z id z 减少为 z id z首先 给予id
  • Scala 中的高级类型 [重复]

    这个问题在这里已经有答案了 我正在阅读 Scala 中的函数式编程一书 在 Monoids 章节中 他们讨论了 Monoid 接口 如下所示 trait Monoid A def op a1 A a2 A A def zero A 后来 他
  • 在 AKKA 中,对主管调用 shutdown 是否会停止其监督的所有参与者?

    假设我有一位主管连接了 2 位演员 当我的应用程序关闭时 我想优雅地关闭这些参与者 调用supervisor shutdown 是否会停止所有参与者 还是我仍然需要手动停止我的参与者 gracias 阻止主管 https github co

随机推荐

  • 如何使用默认 R 安装通过 conda 安装 rpy2

    我在 Ubuntu Linux 上使用 Anaconda Python 发行版 并希望在 IPython 笔记本中使用 R 魔法 有没有办法使用 conda 发行版安装 rpy2 并使用我当前在 usr bin R 的默认 R 安装 我的目
  • codeigniter 在 find_in_set 中添加 IS NULL

    通过生成查询时代码点火器框架 this gt db gt select id memo sent to sent by read by date gt from memos gt where FIND IN SET 1 sent to gt
  • Zxing有时会从条形码中获取错误的数据

    我知道这可能是一个相当简单的问题 我们还可以设置 Zxing 扫描的条形码格式 如下所示 1 intent putExtra SCAN MODE QR CODE MODE or any other format 如果我们这样做 2 inte
  • 什么时候优化为时过早? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我看到这个词用得很多 但我
  • Xcode 5:代码签名权利错误

    我已经构建了一个支持 IOS 7 的新应用程序 我获得了新的 XCode 5 GM 并尝试使用我的新配置文件和分发证书来签署我的应用程序 但我在分发时遇到了问题 我不断收到以下错误 无效的代码签名权利 您的应用程序中的权利 包签名与包含在包
  • 拆分一列字符向量并返回一个列表

    我有以下内容数据框 df lt data frame Sl No c 1 6 Variable c a a b a b c b c b c Sl No Variable 1 a 2 a b 3 a b c 4 b 5 c 6 b c 我想将
  • os/exec StdoutPipe 带颜色

    我正在制作一个包装纸我的世界使用 Go 的服务器控制台 它使用 os exec 运行服务器和 process StdoutPipe 以获取子进程的实时输出 但是 由于某种原因我无法让它显示颜色 当我直接从终端运行服务器时 颜色可以工作 但当
  • 如何忽略包含在我的yarn.lock 文件中的包?

    因此 在我的 package json 中 我有一堆 npm 库 以及一个从 git ssh url 拉入的私有存储库 该存储库需要始终是最新版本 该yarn lock添加了git sha和yarn升级等不会获取最新的 基本上 鉴于此 de
  • 如何通过 Socket 连接接收大数据流 - 没有 TCPClient

    我有一个问题 我想通过 SocketConnection 发送一个大字符串 但我无法立即接收该字符串 因为网络限制为 1500 字节 那么如何在不使用 TCPClient 的情况下通过 Socket 接收所有字节 或者这是不可能的 publ
  • 如何在类路径中使用嵌入表达式

    我试图将文件的绝对值传递给类路径的读取函数 如果我传递绝对路径和类路径 它就可以正常工作 但是当我传递嵌入表达式时它不起作用 我的代码如下 Scenario create swagger first RAD 给定 url 应用服务器 给定参
  • 在 PrintDialog 中以编程方式选择打印机

    我在 Windows 窗体中有一个 Web 浏览器控件 它加载一个 HTML 文件 我希望能够为用户提供将其另存为 PDF 文件的选项 如果用户安装了 CutePDF Writer 那么我想我可以通过编程方式从打印对话框中选择它并将其另存为
  • jQuery 中的 this 和 $(this) 有什么区别?

    jQuery 中的 this 和 this 有什么区别 我什么时候应该使用哪个 p each function this id this attr id 如果您考虑上面的函数 jQuery 将循环访问页面上的每个段落元素 并通过将 this
  • 如何可靠地猜测 MacRoman、CP1252、Latin1、UTF-8 和 ASCII 之间的编码 [重复]

    这个问题在这里已经有答案了 在工作中 似乎每周都会遇到一些与编码相关的忧虑 灾难或灾难 该问题通常源于程序员认为他们可以在不指定编码的情况下可靠地处理 文本 文件 但你不能 因此决定从今以后禁止文件名以以下结尾 txt or text 人们
  • 错误“‘git’未被识别为内部或外部命令”

    我安装了 Windows 版 Git 但是当我尝试使用git命令提示符中的命令 我收到以下错误 git is not recognized as an internal or external command operable progra
  • 是否可以从列表中的项目获取索引?

    我的意思是 我有一个列表框 我将列表放入 itemsSource 属性中 我还想显示它的绑定中的索引 我不知道这在 WPF 中是否可行 谢谢 有几种方法可以做到这一点 包括使用 AlternationIndex 的一些解决方法 但是 由于我
  • iOS,将文件从收件箱文件夹复制到文档路径

    我启用了文档类型以将文件从其他应用程序导入或复制到我的应用程序 我有一些疑问 1 应该在哪里创建将文件从收件箱移动到文档目录的方法 这是正确的地方吗 func applicationWillEnterForeground applicati
  • 将语音输出解析为 JSON 以调用应用程序 API

    这是一个想法 我们有带有公开的 Restful API 的 Web 应用程序 它接受 json 现在 如何使用 Google 语音 API 获取用户语音输入 将其转换为文本 然后以某种方式将该文本转换为 API 所需的 JSON 然后使用
  • 未找到样式属性 attr/@attr/minTextSize

    我长期以来一直在尝试找出问题所在 但不幸的是无法 If I do android enableAapt2 true 代码工作正常 但是删除相同的代码 应该是强制的 会抛出错误 incremental mergeDevDebugResourc
  • 如何合并两个文件?

    我有两个文件 File 1 7118 7457 7591 7539 8001 File 2 5003 5008 5011 5026 5028 5029 5031 我需要的输出 7118 5003 7457 5003 7591 5003 75
  • Scala 中的右关联方法有什么好处?

    我刚刚开始使用 Scala 并且刚刚了解了如何创建方法右结合 与更传统的左结合性在命令式面向对象语言中很常见 起初 当我看到示例代码时consScala 中的列表 我注意到每个示例总是在右侧有列表 println 1 List 2 3 4