2

我想定义一个使用 type 参数化的方法,该方法的T行为取决于可以找到 type 的隐式参数Box[T]。以下代码将此方法定义为foo. foo[Int]当使用or调用时foo[String],它将没有问题返回1"two"按预期返回。

事情变得奇怪的地方是方法栏。它被定义为返回一个Int,而不是foo[Int]我只是foo。我希望编译器会推断出它T必须是 type Int。它没有这样做,而是失败了:

bash $ scalac Code.scala 
Types.scala:15: error: ambiguous implicit values:
 both value one in object Main of type => Main.Box[Int]
 and value two in object Main of type => Main.Box[java.lang.String]
 match expected type Main.Box[T]
 def bar: Int = foo
             ^
one error found

是什么导致了这个错误?替换foofoo[Int]编译很好。没有类型的更简单的情况Box[T]也可以正常编译。该示例也在下面,并使用argleandbargle代替fooand bar

object Main extends Application {

  case class Box[T](value: T)

  implicit val one = Box(1)
  implicit val two = Box("two")

  def foo[T](implicit x: Box[T]): T = {
    x.value
  }

  // does not compile:
  // def bar: Int = foo

  // does compile
  def bar: Int = foo[Int]

  println(bar)
  // prints 1

  // the simpler situation where there is no Box type

  implicit val three = 3
  implicit val four = "four"

  def argle[T](implicit x: T): T = x
  def bargle: String = argle

  println(bargle)
  // prints "four"

}

这个片段中发生了什么导致这种行为?隐式参数、类型推断和擦除之间的交互会导致问题吗?有没有办法修改此代码以使该行def foo: Int = bar正常工作?

4

2 回答 2

1

这可能与SI-3346相关,尽管它有隐式转换的隐式参数,在这里你有一个隐式的。

于 2012-07-03T18:02:47.923 回答
1

其他人将不得不解释为什么类型推断机制无法处理这种情况,但如果您正在寻找清理代码,您可能会这样做:

object Test extends App {

  case class Box[T](value: T)

  implicit val one: Box[Int] = Box(1)
  implicit val two: Box[String] = Box("two")

  def foo[T : Box]: T = implicitly[Box[T]].value  
  val bar = foo[Int]  
}

注意:

  1. 我从中删除了类型注释,bar因此您实际上只是指示了一次类型(只是在与您想要的不同的位置)
  2. 我正在使用App而不是弃用Application
  3. 使用类型签名中绑定的上下文foo
于 2012-07-03T02:59:29.490 回答