gpt4 book ai didi

scala - 在 Scala 中使用高阶函数时,命名参数与 _、点符号与中缀操作、大括号与圆括号

转载 作者:行者123 更新时间:2023-12-02 01:44:36 25 4
gpt4 key购买 nike

我很难理解什么时候可以或不能省略括号和/或句点,以及这与 _ 的相互作用。

我遇到的具体情况是

val x: X = ???
val xss: List[List[X]] = ???
xss map x :: _ //this doesn't compile
xss map _.::(x) //this is the same as the above (and thus doesn't compile)

上面两个好像和xss.map(_).::(x)一样

xss map (x :: _) //this works as expected
xss map {x :: _} //this does the same thing as the above

同时,以下也失败了:

xss.map xs => x :: xs //';' expected but '=>' found.
xss.map x :: _ //missing arguments for method map in class List; follow this method with `_' if you want to treat it as a partially applied function
//so when I try following the method with _, I get my favourite:
xss.map _ x :: _ //Cannot construct a collection of type That with elements of type B based on a collection of type List[List[Main.X]]
//as opposed to
xss map _ x :: _ //missing parameter type for expanded function ((x$1) => xss.map(x$1).x(($colon$colon: (() => <empty>))))

现在,我经常玩“切换符号直到它编译”,我认为这是一种次优的编程策略。这一切是如何运作的?

最佳答案

首先我们需要区分xss.map(f)xss map f。根据Scala Documentation任何采用单个参数的方法都可以用作中缀运算符。

实际上 map method in List是这些方法之一。忽略完整的签名以及它继承自 TraversableLike 的事实,签名如下:

final def map[B](f: (A) ⇒ B): List[B]

所以它只有一个参数,即f,它是一个类型为A => B的函数。所以如果你有一个 function value定义为

val mySize = (xs:List[Int]) => xs.size

你可以选择

xss.map(mySize)

xss map mySize

这是一个偏好问题,但根据 Scala Style Guide ,对于这种情况,后者是首选,除非它是复杂表达式的一部分,最好坚持使用点符号。

请注意,如果您选择使用点符号,则始终需要使用方括号来限定函数应用程序!这就是为什么以下都无法成功编译的原因。

xss.map xs => x :: xs // Won't compile
xss.map x :: _ // Won't compile
xss.map _ x :: _ // Won't compile

但大多数情况下,您需要传递 function literal 而不是传递函数值(又名 anonymous function )。在这种情况下,如果您使用点符号,则需要类似 xss.map(_.size) 的东西。但是如果你使用中缀表示法,这将是一个优先事项。

例如

xss map x :: _ // Won't compile!

由于运算符优先级而不起作用。所以你需要使用括号来为编译器通过xss map (x::_)消除歧义。

使用花括号代替方括号有一个非常清晰和简单的规则。同样,任何只接受一个参数的函数都可以用花括号而不是括号来应用,用于中缀和点符号。所以下面的语句将编译。

xss.map{x :: _}
xss map {x :: _}

为避免混淆,您可以从点符号和参数的显式类型开始。稍后在编译之后 - 并且可能为您的代码编写一些单元测试 - 您可以通过删除不必要的类型、使用中缀表示法以及在有意义的地方使用大括号而不是方括号来开始重构代码。

为此您可以引用Scala Style GuideMartin Odersky's talk in Scala Days 2013这与 Scala 编码风格有关。此外,您始终可以向 IDE 寻求帮助,以重构代码以使其更简洁。

关于scala - 在 Scala 中使用高阶函数时,命名参数与 _、点符号与中缀操作、大括号与圆括号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26438916/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com