Scala:value ::不是Int的成员

时间:2014-07-10 16:27:57

标签: scala

我最近开始使用scala,但我无法做出任何错误消息。对于以下代码,我得到了声明的消息(使用eclipse):

def helper: Int => List[Int] = x =>  x match  {
    case 2 => 2::1
    ...
}

我可以使用List(2,1)修复它,但是它与2 :: 1是一样的吗? 我有类似的问题,List(...)方法会更难使用,所以我真的想知道我的思维错误在哪里。

4 个答案:

答案 0 :(得分:11)

中缀运算符被解释为Scala中的方法调用。如果中缀运算符以冒号结束,则它是对右操作数的方法调用,左操作数作为其参数。否则,它是对左操作数的方法调用,右操作数作为其参数。

换句话说,如果您执行x + y,则它与x.+(y)相同,即您在对象+上调用方法xy 1}}作为参数。如果你x :: y y.::(x)::相同,则在对象y上调用方法::

因此,在您的示例中,您在对象1上调用方法Int,这是一个Int。但是,类::没有::方法,因此这不起作用,并且您收到一条错误消息,告诉您Int方法不存在::类。

要使::正常工作,右侧操作数必须是一个列表(或其他具有2 :: 1 :: Nil方法的内容),因此List()可以正常工作。但是在这种情况下使用{{1}}似乎是更清洁的选择。

答案 1 :(得分:3)

表达式2::1在Scala中被解释为:

{ val x = 2; 1.::(x) }

因为以冒号:结尾的运算符是右关联的,如果op是右关联的,则e1 op e2被解释为{ val x = e1; e2.op(x) }(请参阅Scala Language Reference, Section 6.12.3, p. 84, which is p. 92 of the PDF })。

出于此目的,基本上以下简化版本称为

1.::(2)

但是,1的类型为IntInt没有名称为::的方法(并且也没有隐式转换为具有此类型的另一种类型方法),因此错误。

正如ayvango上面指出的那样,你可以使用

2::1::Nil

被解释为

Nil.::(2).::(1)

现在这非常有效,因为Nil的类型为List[Nothing]并且方法有::,请参阅scala.collection.immutable.List此外,::会返回键入List[Int],以便后续调用.::(1)也可以。

另一种方式是

2::List(1)

变为List(1).::(2)并且与上述原因相同。

您的混淆可能是因为您认为List(2,1)2::1相同,但实际上是2::1::Nil。将列表视为按归纳方式构建如下:

  • Nil是一个列表
  • 如果head是一个元素且tail是一个列表,那么head::tail就是一个列表

如列表的实施(简化版,省略特征)所见证的

sealed abstract class List[+A]
final case class ::[B](head: B, tl: List[B]) extends List[B]
object Nil extends List[Nothing]

因此,列表始终以Nil演示形式“以”::结尾。

在旁注中,您还可以尝试使用

之类的内容自动将Int包裹到List[Int]
implicit def wrap(x : Int) : List[Int] = List(x)

或使用Scalaz等库提供的类似功能,但这可能并不总是可取的,可能有点超出了这个问题的范围。

答案 2 :(得分:2)

::是List上定义的方法。您正尝试将此运算符与Int类型一起使用。 看看:http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.List

正如@ayvango指出的那样,你可以这样做:

def helper: Int => List[Int] = x =>  x match  {
  case 2 => 2 :: 1 :: Nil
}

答案 3 :(得分:0)

如果要使用::Int等其他类型的string运算符,只需在列表末尾添加 Nil ,否则,出现此错误:

  

value ::不是Int的成员

不会会被编译:

println(0::1::2::3::4::5)

但这将被编译:

 println(0::1::2::3::4::5::Nil)

value :: is not a member of Int