观看标题为Scala Type Members vs Type Parameters的youtube视频后。我写了以下内容。
Purely Type参数版本可以正常使用
trait Joiner[Elem,R] {
def join(xs: Seq[Elem]): R
}
object Program {
def doJoin[T,R] (xs: T *) (implicit j: Joiner[T,R] ): R = j.join (xs)
def main(args: Array[String]): Unit = {
implicit val charToStringJoiner = new Joiner[Char,String] {
override def join(xs: Seq[Char]): String = xs.mkString("+")
}
implicit val charToInt = new Joiner[Char,Int] {
override def join(xs: Seq[Char]): Int = xs.mkString.toInt
}
val s:String = doJoin[Char,String]('1','2')
println(s)
val n :Int = doJoin[Char,Int]('1','2')
println(n)
}
}
混合型会员&参数版本 -
trait Joiner[Elem] {
type R
def join(xs: Seq[Elem]): R
}
object Program {
def doJoin[T] (xs: T *) (implicit j: Joiner[T] ): j.R = j.join (xs)
def main(args: Array[String]): Unit = {
implicit val charToStringJoiner = new Joiner[Char] {
override type R = String
override def join(xs: Seq[Char]): String = xs.mkString("+")
}
implicit val charToInt = new Joiner[Char] {
override type R = Int
override def join(xs: Seq[Char]): Int = xs.mkString.toInt
}
val s:String = doJoin('1','2') //doesn't work
println(s)
val n :Int = doJoin('1','2') //doesn't work
println(n)
}
}
版本1很好,但版本2不能编译。如何在隐含范围内修复此问题?具体来说,我如何指定有助于编译器解析正确的隐式
的返回类型答案 0 :(得分:0)
问题是你有两个隐式val,范围内的Joiner [Char]类型相同。 将它们拆分为不同的功能,它应该可以工作:
object Program {
def doJoin[T] (xs: T *) (implicit j: Joiner[T] ): j.R = j.join (xs)
def main(args: Array[String]): Unit = {
def do1: Unit ={
implicit val charToStringJoiner = new Joiner[Char] {
override type R = String
override def join(xs: Seq[Char]): String = xs.mkString("+")
}
val s:String = doJoin('1','2') //doesn't work
println(s)
}
def do2: Unit ={
implicit val charToInt = new Joiner[Char] {
override type R = Int
override def join(xs: Seq[Char]): Int = xs.mkString.toInt
}
val n :Int = doJoin('1','2') //doesn't work
println(n)
}
do1
do2
}
}
答案 1 :(得分:0)
这个怎么样?您可以指定返回类型,输入类型取自参数。
import scala.language.reflectiveCalls
trait Joiner[T, R] {
def join(xs: Seq[T]): R
}
def doJoin[R] = new {
def apply[T](xs: T*)(implicit j: Joiner[T, R]): R = j.join(xs)
}
implicit val charToStringJoiner = new Joiner[Char, String] {
override def join(xs: Seq[Char]): String = xs.mkString("+")
}
implicit val charToInt = new Joiner[Char, Int] {
override def join(xs: Seq[Char]): Int = xs.mkString.toInt
}
implicit val addJoiner = new Joiner[Int, Int] {
override def join(xs: Seq[Int]): Int = xs.sum
}
println(doJoin[String]('1', '2'))
println(doJoin[Int]('1', '2'))
println(doJoin[Int](1, 2))