编译器在期望String的地方期望Long

时间:2019-04-19 00:17:42

标签: scala

在此代码中,编译器消息说它期望“ j”为String,但根据方法中参数的类型,它为Long。

我添加了方法add来表示类型,因此应该不需要推断。如果删除+“ j”并放置一个常数,问题仍然存在。如果我省略“ + j”,它将进行编译。它的行为就像“ that.v”被隐式转换为String一样。但是“ v”显然是参数列表中的Long。

我还将指出“ +”的原因。我实际上想要“ |”但是编译器说Long不支持“ |”。因此,提示如何按位或Long或Int会有所帮助。我的猜测是这些都是经过签名的,也许应该使用针对未签名工作的特定类。

我已将trait类放入具有相同结果的对象中,这正是我所期望的。我尝试了各种导入,例如Long,结果是相同的。

我想知道环境是否存在一些根本问题,例如隐藏的进口。在Odersky中处理代码时,我正在使用最新的IntelliJ。我在另一个文件中有Rational类,并且可以正常编译。

对于新的Scala程序员并不明显的基本知识,我深信不疑。

package com.proclivis.field

trait CommandField[A] {
  def |: (that: CommandField[A]):CommandField[A]
}

class IntCommandField[Long] (val v: Long) extends CommandField[Long] {
  def |: (that: IntCommandField[Long]): IntCommandField[Long] =
    new IntCommandField(add(that.v, this.v))

  private def add (i:Long, j:Long): Long = i + j
}

错误:(21,48)类型不匹配;  找到:长  必需:字符串   私人def add(i:Long,j:Long):Long = i + j

2 个答案:

答案 0 :(得分:1)

问题是这条线

class IntCommandField[Long] (val v: Long) ...

解决方案是删除[Long]

当前声明定义了一个通用类,其中通用类型称为Long。在此类中,Long指的是该通用类,与称为Long的内置类型无关。

当编译器看到此内容

private def add (i:Long, j:Long): Long = i + j

看到一个+运算符应用了两个泛型类型的值。 Scala在所有使用+的类型上定义了通用String,因此它尝试使用它。由于j不是String,因此您会看到错误消息。

答案 1 :(得分:0)

以下操作不会将Long隐式转换为String(您需要从Long中删除IntCommandField类型的注释):

trait CommandField[A] {
  val v: A
  def |: (that: CommandField[A]):CommandField[A]
}

class IntCommandField(val v: Long) extends CommandField[Long] {
  override def |: (that: CommandField[Long]): CommandField[Long] =
    new IntCommandField(add(that.v, this.v))

  private def add(i:Long, j:Long): Long = i + j
}

代码中的另一个问题:

  • 如果将override关键字放在|:方法声明之前,则编译器会抱怨Method |: overrides nothing。上面的代码解决了这个问题。