【问题标题】:Compiler expecting String where it should be expecting Long编译器期望 String 应该期望 Long
【发布时间】:2019-04-19 00:17:42
【问题描述】:

在这段代码中,编译器消息说它期望“j”是字符串,但根据方法中参数的类型,它是 Long。

我添加了方法 add 来表达类型,因此不需要推理。如果我删除 + "j" 并输入一个常数,问题仍然存在。如果我不使用“+ j”,它就会编译。它的行为就像“that.v”隐式转换为字符串。但是“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) 类型不匹配; 发现:长 必需:字符串 private def add (i:Long, j:Long): Long = i + j

【问题讨论】:

    标签: scala


    【解决方案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 您会收到您看到的错误消息。

    【讨论】:

      【解决方案2】:

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

      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。上面的代码解决了这个问题。

      【讨论】:

      • 好的,所以我看到了几件事:A)类中的 def 必须与特征的类型匹配,即使返回值是类 B)这意味着值“v”必须在特征 C) 不要像 IntCommandField[Long] 这样将类型添加到类中 事后看来,我应该发现 C,但是编译器错误导致焦点在错误的位置。目前尚不清楚编译器试图对字符串做什么,也不清楚为什么它没有直接抱怨 C。嗯,也许它使用了[Long]作为类型变量,并且它被排除在new之外,但是不清楚它与字符串的关系。
      • @MikeJones 编译器不知道i 的类型,因此它使用在所有类型上定义的通用+。这个+ 接受String 参数,但j 不是String,所以它给出了你看到的错误。
      猜你喜欢
      • 2016-08-31
      • 1970-01-01
      • 1970-01-01
      • 2021-04-01
      • 2020-06-09
      • 2015-04-21
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多