2016-02-13 229 views
0

我尝试写一些代码转换的隐含参数,喜欢的隐式转换如下:斯卡拉隐含参数

case class A() 
case class B() 
object B { 
    implicit def b2a(b: B): A = new A() 
} 

def foo(f: B => String) = f(new B()) 
def bar(implicit a: A) = "A" 

foo { implicit b => 
    bar() 
} 

给出了错误:

<console>:27: error: not enough arguments for method bar: (implicit a: A)String. 
Unspecified value parameter a. 

有没有一种办法使用隐式转换而不手动调用它?

+1

这不是一个答案,但你绝对肯定你需要这样做吗?你已经看到了一个令人困惑的混乱情况,那就是不得不推断这些暗示将如何解决 - 你是否真的想对每个使用你的代码的人强加这种困惑? –

+0

我同意。这比它值得的更麻烦,但我接受了@ m-z的回答,因为它解决了这个问题。 – pschorf

回答

2

我相信这打破了“一次一个”的规则。在您致电bar的范围内没有隐含的A,只有隐含的B。如果编译器试图隐式地将隐式B转换为A,那将是两个步骤,而不是一个步骤。

但是,您可以通过隐式链接解决此问题。

implicit def a(implicit b: B): A = new A() 

如果此方法是在范围内,则编译器将看到在范围的隐式A,只要它可以填充隐B,它可以。

scala> foo { implicit b => bar } 
res1: String = A 

你遇到的具体错误是因为你需要删除括号,我在这里做了。这会导致上述的“隐含未找到”错误。

+0

可以通过将它放入“A”而不是“B”的伴随对象来使其始终处于范围内。 – Kolmar

+0

'“一次一个”规则“ - 你能否提供一个链接,m-z? –

+0

@KevinMeredith [Odersky,Spoon和Venners在Scala 21.2中编程](https://www.artima.com/pins1ed/implicit-conversions-and-parameters.html#21.2) –