什么时候应该使用.empty而不是单例空实例? [英] When should .empty be used versus the singleton empty instance?

查看:100
本文介绍了什么时候应该使用.empty而不是单例空实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Scala中使用集合时,通常需要将集合的空实例用于基本案例。因为默认的空实例使用 Nothing 的类型参数扩展了集合类型类,所以有时无法直接使用类型推断。例如:

Working with collections in Scala, it's common to need to use the empty instance of the collection for a base case. Because the default empty instances extend the collection type class with a type parameter of Nothing, it sometimes defeats type inference to use them directly. For example:

scala> List(1, 2, 3).foldLeft(Nil)((x, y) => x :+ y.toString())
<console>:8: error: type mismatch;
 found   : List[String]
 required: scala.collection.immutable.Nil.type
              List(1, 2, 3).foldLeft(Nil)((x, y) => x :+ y.toString())

                                                  ^

失败,但是以下两个更正成功了:

fails, but the following two corrections succeed:

scala> List(1, 2, 3).foldLeft(Nil: List[String])((x, y) => x :+ y.toString())
res9: List[String] = List(1, 2, 3)

scala> List(1, 2, 3).foldLeft(List.empty[String])((x, y) => x :+ y.toString())
res10: List[String] = List(1, 2, 3)

我遇到类似难题的另一个地方是定义默认参数。这些是我想到的唯一例子,但我知道我也见过其他人。通常,提供正确类型提示的一种方法是否比另一种更好?

Another place I've run into a similar dilemma is in defining default parameters. These are the only examples I could think of off the top of my head, but I know I've seen others. Is one method of providing the correct type hinting preferable to the other in general? Are there places where each would be advantageous?

推荐答案

我倾向于使用 Nil (或 None )结合告诉类型参数化方法针对特定用例的类型(如Kigyo) 。尽管我认为对于给定的用例,使用显式类型注释同样可以。但我认为在某些情况下,您想坚持使用 .empty ,例如,如果尝试在上调用方法,则无:列表[String] 您首先必须将其用大括号括起来,这样就可以再增加2个字符!

I tend to use Nil (or None) in combination with telling the type parameterized method the type (like Kigyo) for the specific use case given. Though I think using explicit type annotation is equally OK for the use case given. But I think there are use cases where you want to stick to using .empty, for example, if you try to call a method on Nil: List[String] you first have to wrap it in braces, so that's 2 extra characters!!.

现在使用 .empty 的另一个参数是与整个集合层次结构保持一致。例如,您不能执行 Nil:Set [String] ,而您不能执行 Nil:Option [String] ,但您可以执行 Set.empty [String] Option.empty [String] 。因此,除非您真正确定您的代码永远不会重构到其他集合中,否则您应该使用 .empty ,因为重构所需的资源更少。此外,保持一致通常很不错吧? :)

Now the other argument for using .empty is consistency with the entire collections hierarchy. For example you can't do Nil: Set[String] and you can't do Nil: Option[String] but you can do Set.empty[String] and Option.empty[String]. So unless your really sure your code will never be refactored into some other collection then you should use .empty as it will require less faff to refactor. Furthermore it's just generally nice to be consistent right? :)

为了公平起见,我经常使用 Nil None 因为我经常很确定我永远不想使用 Set 或其他东西,实际上我会说最好使用 Nil ,当您确定只处理列表时,因为它告诉读者代码我真的在这里处理列表。

To be fair I often use Nil and None as I'm often quite sure I'd never want to use a Set or something else, in fact I'd say it's better to use Nil when your really sure your only going to deal with lists because it tells the reader of the code "I'm really really dealing with lists here".

最后,您可以使用 .empty 和鸭子输入来做一些很酷的事情,请检查以下简单示例:

Finally, you can do some cool stuff with .empty and duck typing check this simple example:

def printEmptyThing[K[_], T <: {def empty[A] : K[A]}](c: T): Unit = 
  println("thing = " + c.empty[String])

printEmptyThing[List, List.type](List)
printEmptyThing[Option, Option.type](Option)
printEmptyThing[Set, Set.type](Set)

将打印:

> thing = List()

> thing = None

> thing = Set()

这篇关于什么时候应该使用.empty而不是单例空实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆