gpt4 book ai didi

scala - cons 是方法还是类?

转载 作者:行者123 更新时间:2023-12-04 01:42:24 27 4
gpt4 key购买 nike

马丁·奥德斯基在他的书中写道:

Class ::, pronounced “cons” for “construct,” represents non-empty lists.





The list construction methods :: and ::: are special. Because they end in a colon, they are bound to their right operand. That is, an operation such as x :: xs is treated as the method call xs.::(x), not x.::(xs). In fact, x.::(xs) would not make sense, as x is of the list element type, which can be arbitrary, so we cannot assume that this type would have a :: method. For this reason, the :: method should take an element value and yield a new list


::也是如此一个方法还是一个类?

最佳答案

它既是 class和一个 method . Cons 是一个类型参数化的类。 List[A] 有两个子类:Cons 和 Nil。由于 Cons 是一个类,它可以通过其构造函数创建,如下所示:

val s = new ::[Int](4, Nil)

Cons 是一个 case 类,我们在进行模式匹配时使用构造函数。 Cons 也是列表类上的一个方法,在其两个子类中实现。因此,我们可以在上面创建的 cons 类上使用 cons 方法。
val s1 = s.::(5)

部分混淆可能会出现,因为我们通常使用 List 对象的 apply 方法创建 Lists:
val s2 = List(1, 2, 3)

通常,对象的 apply 方法返回与对象同名的类的新实例。然而,这只是惯例。在这种特殊情况下,列表对象返回 Cons 子类的新实例。 List 类本身是一个密封的抽象类,因此无法实例化。所以上面的apply方法做了以下事情:
val s2 = 1 :: 2 :: 3 :: Nil

任何以“:”结尾的方法都是其右侧操作数上的方法,因此可以将其重写为
val s2 = 1 :: (2 :: (3 :: Nil)) //or as
val s2 = Nil.::(3).::(2).::(1)

因此,Nil 对象上的 Cons(::) 方法将 3 作为参数,并生成 Cons 类的匿名实例化,以 3 作为头部,对 Nil 对象的引用作为尾部。让我们称这个匿名对象为 c1。然后在 c1 上调用 Cons 方法,将 2 作为其参数,返回一个新的匿名 Cons 实例,我们称之为 c2,其头部为 2,尾部为对 c1 的引用。最后,c2 对象上的 cons 方法将 1 作为参数并返回命名对象 s2,其中 1 作为头部,对 c2 的引用作为尾部。

第二个混淆点是 REPL 和 Scala 工作表使用类的 toString 方法来显示结果。所以工作表给了我们:
val s3 = List(5, 6, 7)     // s3  : List[Int] = List(5, 6, 7)
val s4 = List() // s4 : List[Nothing] = List()
val s5: List[Int] = List() // s5 : List[Int] = List()
s3.getClass.getName // res3: String = scala.collection.immutable.$colon$colon
s4.getClass.getName // res4: String = scala.collection.immutable.Nil$
s5.getClass.getName // res5: String = scala.collection.immutable.Nil$

如上所述,List 是密封的,因此无法创建新的子子类,因为 Nil 是一个对象,而 Cons 是最终的。由于 Nil 是一个对象,它不能被参数化。 Nil 继承自 List[Nothing]。乍一看这听起来没什么用,但请记住这些数据结构是不可变的,所以我们永远不能直接添加它们,而且 Nothing 是所有其他类的子类。所以我们可以毫无问题地将 Nil 类(间接地)添加到任何 List 中。 Cons 类有两个成员,一个是 head,另一个是 List。当你计时它时,它是一个相当巧妙的解决方案。

我不确定这是否有任何实际用途,但您可以使用 Cons 作为一种类型:
var list: ::[Int] = List (1,2,3).asInstanceOf[::[Int]]
println("Initialised List")
val list1 = Nil
list = list1.asInstanceOf[::[Int]] //this will throw a java class cast exception at run time
println("Reset List")

关于scala - cons 是方法还是类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19426548/

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