簡體   English   中英

我的函數的擴展函數缺少參數類型; 不是另一個有相同簽名的人

[英]missing parameter type for expanded function for my function; not for another with same signature

簡短形式 :我有一個與Future.recover具有相同簽名的方法。 將部分函數傳遞給Future的版本。 將相同的PF傳遞給我的版本會導致missing parameter type for expanded function. The argument types of an anonymous function must be fully known. (SLS 8.5) missing parameter type for expanded function. The argument types of an anonymous function must be fully known. (SLS 8.5) missing parameter type for expanded function. The argument types of an anonymous function must be fully known. (SLS 8.5)錯誤。 有什么不同?

更長的形式 :我正在嘗試實現此處討論的TracingFuture類,以嘗試跟蹤未來邊界的錯誤。 基本技術是將Future包裝在另一個類TracingFuture ,同時添加偽TracingFuture

博客文章中給出的代碼缺少Futurerecover方法,所以我添加了相同的簽名:

class TracingFuture[+T](underlying: Future[T], val trace: Vector[FutureTraceElement]) extends Future[T] {

  def recover[U >: T](pf: PartialFunction[Throwable, U]
                     )(implicit ec: ExecutionContext, enclosing: sourcecode.Enclosing, file: sourcecode.File,
                       line: sourcecode.Line): TracingFuture[U] = {
    val recovered = underlying.recover(pf)
    new TracingFuture[U](recovered, trace :+ FutureTraceElement(enclosing.value, "recover", file.value, line.value))

  }

}

為了比較,這里是Future的等效代碼塊。 請注意,除了額外的隱式參數外,簽名是相同的。

trait Future[+T] extends Awaitable[T] {

  def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] =
    transform { _ recover pf }
}

最后,我的代碼產生編譯錯誤:

val x: TracingFuture[Vector[Maintainer]] = ... // code producing a TracingFuture
val fMaintainers = x.recover {
  case err: Throwable ⇒
    logger.error("Failed to get list of user maintainers.", err)
    Vector.empty[Maintainer]
}

並且錯誤消息:

[error] /Users/bwbecker/oat/src/oat3/modules/wapp/app/oat/wapp/dao/CronJobDAO.scala:273: missing parameter type for expanded function
[error] The argument types of an anonymous function must be fully known. (SLS 8.5)
[error] Expected type was: ?
[error]     val fMaintainers = x.recover {
[error]                                  ^

再次,這個代碼工作與Future.recover ,但我得到一個編譯錯誤TracingFuture.recover 我不明白為什么。

這個SO問題解釋了編譯器知道部分函數的參數必須是T的超類型但不能保證。 但是為什么它與Future.recover不會遇到這個問題呢?

當然,除了重寫匿名部分函數以使類型顯式化之外,我想知道是否有任何關於它的事情。

問題是TracingFuture有兩個重載的recover方法:你添加的方法和你從Future繼承的方法。 當你只有一個時,它提供了對類型推斷至關重要的預期類型,但是使用重載方法它不起作用,正如你在Expected type was: ?看到的那樣Expected type was: ?

您可能認為編譯器應該注意到函數參數的類型是相同的,因此仍然可以提供預期的類型。 你會是對的,但它只在Scala 2.12中得到修復

當然,那么當遇到隱式參數不同時,編譯器無法告訴您需要哪個重載會遇到麻煩。

嘗試更換

val fMaintainers = x.recover {
  case err: Throwable ⇒
    logger.error("Failed to get list of user maintainers.", err)
    Vector.empty[Maintainer]
}

val fMaintainers = x.recover(PartialFunction[Throwable, Vector[Maintainer]] { 
  case err: Throwable ⇒
    logger.error("Failed to get list of user maintainers.", err)
    Vector.empty[Maintainer]
})

為什么我在一個案例中獲得“擴展函數的缺失參數”而不是另一個案例?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM