隐式转换,类型参数,重载和匿名函数语法

时间:2016-03-16 16:35:26

标签: scala implicit-conversion implicit implicits

所以,我试图"皮条客"我的Future(以及其他一些东西)有点像这样:

implicit class Pimp[T](val x: T) extends AnyVal  {
  def ->>[R](f: T => R): R = f(x)
  def ->>[R](r: => R): R = r
  def <<-(f: T => Unit): T = f.andThen(_ => x).apply(x)
  def <<-(f: => Unit): T = <<- { _ => f }
}

出于某种原因,当我现在尝试这样做时:

Future(1) ->> { Await.result(_, 1 seconds) }

它以error: missing parameter type for expanded function ((x$1) => Await.result(x$1, 1.seconds))

失败

但这有效:

Future(1) <<- { Await.result(_, 1 seconds) }

所以,问题是第一种情况出了什么问题。我做错了什么,以及如何让它发挥作用。 我甚至尝试了这个(根本不是我想要的,因为它太冗长了):Future(1) --> { case x: Future[Int] => Awayt.result(_, 1 seconds) },但即使这个因某些原因失败(仍然说参数类型未知 - 如果我明确的话,它怎么知道呢?指定它???)

我怀疑,第一个案例和第二个案例之间的区别在于->>有一个类型参数,而<<-没有...但即使这个Future(1) ->>[Int] { Await.result(_, 1 seconds) }仍然不起作用: (

更新好的,我找到了一种方法:

Future(1) ->> { (f:Future[Int]) => Await.result(f, 1 seconds) }

这有点打败了我隐含的目的,因为它是多么冗长:( 有没有办法让它推断出参数类型而不像其他情况那样拼写出来?

更新2 还有一件事。去除过载的&#34;味道&#34;来自->>的{​​{1}}使另一个案例起作用。即,如果我只离开

Pimp

def ->>[R](f: T => R): R = f(x) 的定义中,然后

Pimp

按照预期精美工作。

考虑到它已经有一段时间了,我想,问题是在重载的情况下Future(1) ->> { Await.result(_, 1 seconds) } 是不明确的:它可能意味着&#34;返回bar&#34;或&#34;返回函数foo =&gt; BAR&#34 ;.但这并不能解释为什么foo ->> { _ => bar }不起作用。

1 个答案:

答案 0 :(得分:0)

您可以缩短对Future(1) ->> { Await.result(_: Future[Int], 1 seconds) }的通话时间。不完美,但比你的更新1更好。更好的是避免在“拉皮条”方法中超载:不出所料,它使类型推断变得复杂。

仔细阅读http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html后,似乎指定[Int] 不应工作:

  1. 整个表达式是函数应用程序(6.6)。

  2. 由于Future(1).->>超载,我们转到6.23。

    1. 备选方案A是由->>引用的成员集; [Int]未被考虑在内,因为该部分讨论了“标识符或选择e”,并且选择为Future(1).->>

    2. shape({ Await.result(_, 1 seconds) })Any => Nothing

    3. “设B是A中适用于类型(形状(e1),...,形状(en))”的表达式(e1,...,en)的备选集合。 A 中的两种方法适用于Any => Nothing(正如您所说,“它可能意味着”返回栏“或”返回函数foo =&gt; bar“)。所以我们去“否则,让S1,...,Sm成为通过键入具有未定义的预期类型的​​每个参数获得的类型的向量”,这种输入失败。

    4. 对于<<-案例,=> Unit不适用(因为此步骤中预期类型不是Unit ,价值丢弃不会发生)。

  3. 但它足够微妙,我在写这个更新时已经改变了主意两次;我我现在就知道了。