头部字段值或方法是否在Scala中?

头部字段值或方法是否在Scala中?,scala,Scala,我在学Scala 我搞不清楚Scala不可变列表中的头是方法还是字段值 清单声明如下 sealed abstract class List[+A] extends .... { def isEmpty: Boolean def head: A //I think it is field value not a function or method def tail: List[A] 但intelliJ说这是一种方法 具体是什么?这是Scala中与traits和abstract cl

我在学Scala

我搞不清楚Scala不可变列表中的头是方法还是字段值

清单声明如下

sealed abstract class List[+A] extends .... {
  def isEmpty: Boolean
  def head: A //I think it is field value not a function or method
  def tail: List[A]
但intelliJ说这是一种方法


具体是什么?

这是Scala中与
trait
s和
abstract class
es一起使用的常见模式:子类中的
val
s可以覆盖字段:

scala> trait A { def foo: String }
defined trait A

scala> class B(val foo: String) extends A
defined class B

scala> new B("hello").foo
res0: String = hello

因此,答案是对于非抛出的具体实现,它将是一个
val
,并且不会在调用堆栈上放置任何内容(请参阅);对于抽象实现或抛出具体实现,它将是一个
def

这是Scala中与
trait
s和
abstract class
es一起使用的常见模式:子类中的
val
s可以覆盖字段:

scala> trait A { def foo: String }
defined trait A

scala> class B(val foo: String) extends A
defined class B

scala> new B("hello").foo
res0: String = hello

因此,答案是对于非抛出的具体实现,它将是一个
val
,并且不会在调用堆栈上放置任何内容(请参阅);对于抽象实现或抛出具体实现,它将是一个
def

List是一个抽象类,
def head
这里是一个抽象方法,所以声明和IJ都是正确的

在列表的非空实例中,即
,它的实现如下所示:

final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {
  override def tail : List[B] = tl
  override def isEmpty: Boolean = false
}
因此,字段
head
用于实现抽象方法
head
。这在Scala中是合法的:
val
和无参数
def
之间没有太大区别,您可以通过二进制兼容的方式在两者之间进行更改

在列表的空实例中,
Nil
,实现此方法以引发异常:

case object Nil extends List[Nothing] {
  override def head: Nothing =
    throw new NoSuchElementException("head of empty list")
/*...*/
}

字段不能“抛出异常”,但方法显然可以。List是一个抽象类,而def head是一个抽象方法,因此声明和IJ都是正确的

在列表的非空实例中,即
,它的实现如下所示:

final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {
  override def tail : List[B] = tl
  override def isEmpty: Boolean = false
}
因此,字段
head
用于实现抽象方法
head
。这在Scala中是合法的:
val
和无参数
def
之间没有太大区别,您可以通过二进制兼容的方式在两者之间进行更改

在列表的空实例中,
Nil
,实现此方法以引发异常:

case object Nil extends List[Nothing] {
  override def head: Nothing =
    throw new NoSuchElementException("head of empty list")
/*...*/
}

字段不能“抛出异常”,但方法显然可以。

正如我们都知道的
scala的层次结构。在所有高级抽象类或traits
中,collection
是可遍历的。 但是当你说

   def head: A //I think it is field value not a function or method
我想说,
head
不是一个字段值,而是一个方法。 如果您转到
TraversableLike
trait,您将发现以下实现

    /** Selects the first element of this $coll.
    *  $orderDependent
    *  @return  the first element of this $coll.
    *  @throws NoSuchElementException if the $coll is empty.
    */
    def head: A = {
    var result: () => A = () => throw new NoSuchElementException
    breakable {
    for (x <- this) {
     result = () => x
     break
     }
    }
    result()
    }
/**选择此$coll的第一个元素。
*$orderDependent
*@返回此$coll的第一个元素。
*如果$coll为空,@将抛出NoSuchElementException。
*/
def头:A={
变量结果:()=>A=()=>抛出新的NoSuchElementException
易碎的{
对于(x
打破
}
}
结果()
}
因此它采用集合类型
List[A]
并检查元素是否为空,然后抛出异常,否则
x
将是
的第一个
元素将返回,循环将被中断


希望这对您有所帮助。

因为我们都知道scala的层次结构。所有高级抽象类或traits中的集合都是父集合。 但是当你说

   def head: A //I think it is field value not a function or method
我想说,
head
不是一个字段值,而是一个方法。 如果您转到
TraversableLike
trait,您将发现以下实现

    /** Selects the first element of this $coll.
    *  $orderDependent
    *  @return  the first element of this $coll.
    *  @throws NoSuchElementException if the $coll is empty.
    */
    def head: A = {
    var result: () => A = () => throw new NoSuchElementException
    breakable {
    for (x <- this) {
     result = () => x
     break
     }
    }
    result()
    }
/**选择此$coll的第一个元素。
*$orderDependent
*@返回此$coll的第一个元素。
*如果$coll为空,@将抛出NoSuchElementException。
*/
def头:A={
变量结果:()=>A=()=>抛出新的NoSuchElementException
易碎的{
对于(x
打破
}
}
结果()
}
因此它采用集合类型
List[A]
并检查元素是否为空,然后抛出异常,否则
x
将是
的第一个
元素将返回,循环将被中断


希望这对您有所帮助。

Scala中有一个叫做统一访问原则的好东西。不幸的是,我无法快速搜索任何好的解释文章。但我建议您检查一下。Scala中有一个叫做统一访问原则的好东西。不幸的是,我无法快速搜索任何好的解释文章。但我建议你去看看。