【问题标题】:Why does apply with function parameter fail for println and not print?为什么 println 的函数参数应用失败而不是打印?
【发布时间】:2020-04-03 16:46:41
【问题描述】:

当我像这样将回调函数传递给 apply 方法时,出现编译错误。

Foo[Int](println) // Error: overloaded method ... cannot be applied to (Unit)Foo[Int](println)
Foo[Int](f = println) // Error: overloaded method ... (f: Unit)Foo[Int](f = println)
Foo[Int]((x:Int) => println(x)) // Works!

起初我认为这是由于缺少参数列表,因为它适用于 print

Foo[Int](print(_)) // works
Foo[Int](f = print(_)) // works
Foo[Int]((x:Int) => print(x)) // works

但是对于println,添加它仍然失败

Foo[Int](println(_)) // Error:(6, 18) missing parameter type for expanded function ((x$1: <error>) => println(x$1)) Foo[Int](println(_)) 
Foo[Int](f = println(_)) // Error:(7, 22) missing parameter type for expanded function ((x$2: <error>) => println(x$2)) Foo[Int](f = println(_))
Foo[Int]((x:Int) => println(x)) // works

为什么传入 println 函数的前两种方法不起作用? 是println()println(x: Any) 的重载导致编译器出现问题吗?

下面是一个完整的例子,包含 Foo 的伴生对象和案例类以及其他一些反应流代码

package test

import org.reactivestreams.{Subscriber, Subscription};

object test extends App {
  Foo[Int](println) // Error: cannot be applied to (Unit)Foo[Int](println)
  Foo[Int](f = println) // Error: (f: Unit)Foo[Int](f = println)
  Foo[Int]((x:Int) => println(x)) // Works!
}

object Foo {
  def apply[T](f: T => Unit): Foo[T] = new Foo(
    new Subscriber[T] {
      override def onSubscribe(s: Subscription): Unit = {}
      override def onNext(t: T): Unit = f(t)
      override def onError(t: Throwable): Unit = {}
      override def onComplete(): Unit = {}
    }
  )
}
case class Foo[T] (delegate: Subscriber[T]) extends Subscriber[T] {
  override def onSubscribe(s: Subscription): Unit = {}
  override def onNext(t: T): Unit = {}
  override def onComplete(): Unit = {}
  override def onError(t: Throwable): Unit = {}
}

【问题讨论】:

    标签: scala


    【解决方案1】:

    确实是println()println(x: Any) 的重载导致了问题。编译器无法推断您指的是这两种方法中的哪一种。

    您可以轻松复制:

    def x(): Unit = ???
    def x(a: String): Unit = ???
    def y(a: String): Unit = ???
    
    Foo[String](x(_)) // doesn't compile
    Foo[String](y(_)) // compiles
    
    Foo[String](x(_: String)) // compiles, force the compiler to use the second implementation
    

    【讨论】:

    • 谢谢!我更喜欢Foo[String](x(_: String)) 语法
    猜你喜欢
    • 1970-01-01
    • 2020-06-09
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    • 2019-10-22
    • 2016-10-17
    相关资源
    最近更新 更多