有一种很好的方法可以让行1.print
无法定义隐式intPrintable
吗?
我想说编译器也在stringPrintable
类型中使用Int
实现而不提供新的implicit Printable[Int]
,我们的想法是向编译器说{{1} }可以被视为Int
这里的例子是:
String
答案 0 :(得分:0)
您的代码需要额外的隐式,因为它需要作为(隐式类)的构造函数PrintableOps
您可以通过简单地直接声明隐式类来简化这一过程:
trait Printable[T] {
def print: String
}
implicit class GenericPrintable[T](in: T) extends Printable[T] {
def print:String = in.toString
}
implicit class StringPrintable(in:String) extends Printable[String]{
override def print:String = s"print ${in}"
}
println( 1.print )
println( "1".print )
答案 1 :(得分:0)
您的stringPrintable
需要使用intToString
将Int转换为String。
implicit val stringPrintable: Printable[String] = Printable((in: String) => s"print $in")
implicit def intToString(i: Int): String = i.toString
Printable.apply()需要匿名函数,匿名函数不能采用隐式值,其中intToString是隐式的。
更好的解决方法是静态定义隐式Printable [Int]或者将Printable改为GenericPrintable [T]并参考@Jon Anderson
答案 2 :(得分:0)
我们需要提供Printer[String] => Printer[Int]
的隐式转换,前提是Int => String
隐式转换。我们可以将其放在Printer
随播广告对象上:
implicit def apply[T0, T1](implicit pin: Printable[T0], c: T1 => T0): Printable[T1] = new Printable[T1] {
def print(in: T1): String = pin.print(c(in))
}
这里是解决方案:
trait Printable[T]{
def print(in: T): String
}
object Printable{
def apply[T](f: T => String): Printable[T] = new Printable[T] {
def print(in: T): String = f(in)
}
implicit def apply[T0, T1](implicit pin: Printable[T0], c: T1 => T0): Printable[T1] = new Printable[T1] {
def print(in: T1): String = pin.print(c(in))
}
}
implicit class PrintableOps[T](v: T)(implicit printable: Printable[T]) {
def print: String = printable.print(v)
}
implicit val stringPrintable: Printable[String] = Printable((in: String) => s"print $in")
implicit def intToString(i: Int): String = i.toString
// now working
1.print
// works
stringPrintable.print(1)
// works
intToString(1).print
// don't compile, and it's ok, because no implicit conversion (A => String) is provided
case class A(in: String)
A("A").print
您怎么看?