Scala:编译错误:方法重载

Posted

技术标签:

【中文标题】Scala:编译错误:方法重载【英文标题】:Scala: Compilation error: Overloaded method 【发布时间】:2020-08-15 15:06:51 【问题描述】:

我使用 the following method call 向 Intellij 导入了一个 Play/Scala 项目,但由于我不明白的原因而出现编译错误。

这个编译错误的原因是什么?

编译器不应该选择正确的重载方法吗?

我正在使用 Java 8、Scala 2.11.7、Play 2.4.3、JOOQ 3.7.1、SBT 0.13.18。

  def receive = 
    case UserRegistered(phoneNumber, userName, timestamp) =>
      database.withTransaction  sql =>
        sql.insertInto(TWITTER_USER)
          .columns(TWITTER_USER.CREATED_ON, TWITTER_USER.PHONE_NUMBER, TWITTER_USER.TWITTER_USER_NAME)
          //THE FOLLOWING METHOD CALL HAS A COMPILATION ERROR:
          .values(new Timestamp(timestamp.getMillis), phoneNumber, userName)
          .execute()
      
    case ClientEvent(phoneNumber, userName, MentionsSubscribed(timestamp), _) =>
      database.withTransaction  sql =>
        sql.insertInto(MENTION_SUBSCRIPTIONS)
          .columns(MENTION_SUBSCRIPTIONS.USER_ID, MENTION_SUBSCRIPTIONS.CREATED_ON)
          .select(
             select(TWITTER_USER.ID, value(new Timestamp(timestamp.getMillis)))
               .from(TWITTER_USER)
               .where(
                 TWITTER_USER.PHONE_NUMBER.equal(phoneNumber)
                 .and(
                   TWITTER_USER.TWITTER_USER_NAME.equal(userName)
                 )
               )
          ).execute()
      
    case ClientEvent(phoneNumber, userName, MentionReceived(id, created_on, from, text, timestamp), _) =>
      database.withTransaction  sql =>
        sql.insertInto(MENTIONS)
          .columns(
            MENTIONS.USER_ID,
            MENTIONS.CREATED_ON,
            MENTIONS.TWEET_ID,
            MENTIONS.AUTHOR_USER_NAME,
            MENTIONS.TEXT
          )
          .select(
             select(
               TWITTER_USER.ID,
               value(new Timestamp(timestamp.getMillis)),
               value(id),
               value(from),
               value(text)
             )
             .from(TWITTER_USER)
             .where(
               TWITTER_USER.PHONE_NUMBER.equal(phoneNumber)
               .and(
                 TWITTER_USER.TWITTER_USER_NAME.equal(userName)
               )
             )
          ).execute()
      
  

如您所见,方法调用.values(new Timestamp(timestamp.getMillis), phoneNumber, userName) 出现编译错误。错误输出为:

[info] Compiling 30 Scala sources and 1 Java source to /home/me/projects/book/CH07/target/scala-2.11/classes...
[error] /home/me/projects/book/CH07/app/actors/CQRSEventHandler.scala:21: overloaded method value values with alternatives:
[error]   (x$1: org.jooq.Field[java.time.OffsetDateTime],x$2: org.jooq.Field[String],x$3: org.jooq.Field[String])org.jooq.InsertValuesStep3[generated.tables.records.TwitterUserRecord,java.time.OffsetDateTime,String,String] <and>
[error]   (x$1: java.time.OffsetDateTime,x$2: String,x$3: String)org.jooq.InsertValuesStep3[generated.tables.records.TwitterUserRecord,java.time.OffsetDateTime,String,String]
[error]  cannot be applied to (java.sql.Timestamp, String, String)
[error]           .values(new Timestamp(timestamp.getMillis), phoneNumber, userName)
[error]            ^
[error] /home/me/projects/book/CH07/app/actors/CQRSEventHandler.scala:31: type mismatch;
[error]  found   : org.jooq.SelectConditionStep[org.jooq.Record2[Long,java.sql.Timestamp]]
[error]  required: org.jooq.Select[_ <: org.jooq.Record2[Long,java.time.OffsetDateTime]]
[error]                .where(
[error]                      ^
[error] /home/me/projects/book/CH07/app/actors/CQRSEventHandler.scala:58: type mismatch;
[error]  found   : org.jooq.SelectConditionStep[org.jooq.Record5[Long,java.sql.Timestamp,String,String,String]]
[error]  required: org.jooq.Select[_ <: org.jooq.Record5[Long,java.time.OffsetDateTime,String,String,String]]
[error]              .where(
[error]                    ^
[error] /home/me/projects/book/CH07/app/actors/CQRSQueryHandler.scala:29: overloaded method value greaterOrEqual with alternatives:
[error]   (x$1: org.jooq.QuantifiedSelect[_ <: org.jooq.Record1[java.time.OffsetDateTime]])org.jooq.Condition <and>
[error]   (x$1: org.jooq.Select[_ <: org.jooq.Record1[java.time.OffsetDateTime]])org.jooq.Condition <and>
[error]   (x$1: org.jooq.Field[java.time.OffsetDateTime])org.jooq.Condition <and>
[error]   (x$1: java.time.OffsetDateTime)org.jooq.Condition
[error]  cannot be applied to (org.jooq.Field[java.sql.Timestamp])
[error]         MENTIONS.CREATED_ON.greaterOrEqual(currentDate().cast(PostgresDataType.TIMESTAMP))
[error]                             ^
[error] four errors found
[error] (compile:compileIncremental) Compilation failed
[error] application - 

! @7fjed5mfe - Internal server error, for (GET) [/] ->

play.sbt.PlayExceptions$CompilationException: Compilation error[Overloaded method value [values] cannot be applied to  (java.sql.Timestamp, String, String)]
        at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27) ~[na:na]
        at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27) ~[na:na]
        at scala.Option.map(Option.scala:145) ~[scala-library-2.11.7.jar:na]
        at play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:49) ~[na:na]
        at play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:44) ~[na:na]
        at scala.Option.map(Option.scala:145) ~[scala-library-2.11.7.jar:na]
        at play.sbt.run.PlayReload$.taskFailureHandler(PlayReload.scala:44) ~[na:na]
        at play.sbt.run.PlayReload$.compileFailure(PlayReload.scala:40) ~[na:na]
        at play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17) ~[na:na]
        at play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17) ~[na:na]

org.jooq.InsertValuesStep3 (3.7.1) 中的重载方法:

package org.jooq;

import java.util.Collection;

import javax.annotation.Generated;

/**
 * This type is used for the @link Insert's DSL API.
 * <p>
 * Example: <code><pre>
 * using(configuration)
 *       .insertInto(table, field1, field2, field3)
 *       .values(field1, field2, field3)
 *       .values(field1, field2, field3)
 *       .onDuplicateKeyUpdate()
 *       .set(field1, value1)
 *       .set(field2, value2)
 *       .execute();
 * </pre></code>
 *
 * @author Lukas Eder
 */
@Generated("This class was generated using jOOQ-tools")
public interface InsertValuesStep3<R extends Record, T1, T2, T3> extends InsertOnDuplicateStep<R> 

    /**
     * Add values to the insert statement.
     */
    @Support
    InsertValuesStep3<R, T1, T2, T3> values(T1 value1, T2 value2, T3 value3);

    /**
     * Add values to the insert statement.
     */
    @Support
    InsertValuesStep3<R, T1, T2, T3> values(Field<T1> value1, Field<T2> value2, Field<T3> value3);

    /**
     * Add values to the insert statement.
     */
    @Support
    InsertValuesStep3<R, T1, T2, T3> values(Collection<?> values);

    /**
     * Use a <code>SELECT</code> statement as the source of values for the
     * <code>INSERT</code> statement
     * <p>
     * This variant of the <code>INSERT .. SELECT</code> statement expects a
     * select returning exactly as many fields as specified previously in the
     * <code>INTO</code> clause:
     * @link DSLContext#insertInto(Table, Field, Field, Field)
     */
    @Support
    InsertOnDuplicateStep<R> select(Select<? extends Record3<T1, T2, T3>> select);

【问题讨论】:

您昨天已经问过一个关于此项目未编译并出现方法重载错误的问题。这是同一个问题。请不要发布重复的问题。这个项目的构建显然有问题。也许并不奇怪,因为它很旧。可能的问题,您使用的 java/scala/sbt 版本不兼容,与项目的依赖项冲突。这些问题确实属于github上的issue page 我不会发布重复的问题。你无权告诉我要从事哪个项目。询问旧项目是合理的,特别是如果我知道我需要复制原始依赖项。没关系,但这本书还没有更新版本,实际项目很有价值。我有足够的经验知道,即使我想升级依赖项,我首先必须让原始代码工作。因为是同一个项目和同一个编译器错误,就得出两个问题相同的结论太简单了:编译器错误通常只是症状。 我无意建议你不能从事这个项目。这看起来很有趣,并且可能对其他人有用。我读这个问题的方式是,为什么我得到这个项目的方法重载编译错误。对我来说,这与您询问的关于同一项目中另一个方法重载编译错误的另一个问题是同一个问题。我同意这是另一个问题的症状,这就是为什么我认为这个问题最好作为一个一般性问题提出,即使用特定 scala/sbt 版本和特定 sbt 配置构建项目 在 SO 上允许您问一个问题“我如何构建这个项目(其中有多个需要更正的点)?”是完全不正确的。没有人会尝试回答它,它会被否决和删除(即使问题是合法的并且写得正确也会发生)。问题需要具体,他们需要尽可能地隔离特定问题,他们需要表明 OP 做了他们的功课,即他们尽最大努力解决问题,但他们走到了死胡同。附言从数学上讲,80% 的人在每个时间点都在使用“旧代码”。 【参考方案1】:

重载消息令人困惑,但真正的问题是代码传递了java.sql.Timestamp,而java.time.OffsetDateTime 是必需的。它们不是兼容的类型。

【讨论】:

如何从org.joda.time.DateTimejava.sql.Timestamp 创建java.time.OffsetDateTime

以上是关于Scala:编译错误:方法重载的主要内容,如果未能解决你的问题,请参考以下文章

重载的包私有方法导致编译失败 - 这是 JLS 怪异还是 javac 错误?

表达式/函数重载的编译器错误

编译期多态和Sfinae

打字稿编译器选择错误的重载

错误:scala:Scala 编译器库中没有“scala-library*.jar”

在 Eclipse IDE 中使用 Scala 代码。内部编译器错误