2017-06-20 28 views
2
implicit class Interpolator(val a: StringContext) extends AnyVal { 
    def foo[A](args: Any*): A = ??? 
} 

val first = foo[String]"myString" // This does not parse 
val second = (new StringContext).foo[String]("myString") // This works but I'm wondering if there is a more concise syntax 
val third = foo"myString"[String] // This one is intriguing because it parses but the compiler outputs "method foo does not take type parameters"... what? 

弦乐插补指定类型参数如果A可以推断那么这一切都很好,因为foo"myString"只会工作,但如果不能,我想知道是否有比second更好的语法允许我指定我期望的类型参数。是否有可能在斯卡拉

回答

2

仅次于编译,但它并没有真正的工作,我们可以尝试例如

implicit class Interpolator(val a: StringContext) extends AnyVal { 
    def foo[A](args: Any*): A = args.head.asInstanceOf[A] 
} 

val a = 2 
val second = (new StringContext)foo[String]"a=$a" 
println(second)// this will print a=$a which is not the expected output 

但下面应该工作

implicit class Interpolator[A](val a: StringContext) extends AnyVal { 
    def foo(args: Any*): A = args.head.asInstanceOf[A] 
} 

val a = 2 
val first :Int = foo"a=$a" // : Int is what that does the trick 
println(first) // will print 2 as expected 
+0

这并没有真正回答这个问题是怎么在使用字符串插值器语法时提供类型参数。虽然第一个代码示例的行为确实很奇怪,但我会承认。 – jedesah

+0

因为每次运行foo都会创建一个新的Interpolator,所以向Interpolator提供类型参数与将它们提供给foo相同。在我的例子中,它们隐式提供...(通过分配给int val)。所以这是你的问题的答案,如果我失去了一些东西,你能否提供一个代码示例,以便理解你在做什么? – oron

+0

我明白了。但是类型论证仍然需要被推断出来,这就是为什么我在问:为什么要指定?我希望可以简单地推断出我正在处理的情况,因为这会使事情变得简单,但不幸的是,情况并非如此。但我现在很好奇为什么第二个例子的行为与第一个例子不同?第一个发生什么事情来产生意想不到的结果? – jedesah