我在文件Show.scala
中具有以下定义:
package com.example
trait Show[A] {
def show(a: A): String
}
object Show {
def apply[A](implicit sh: Show[A]): Show[A] = sh
//def show[A](a:A)(implicit sh: Show[A]) = sh.show(a)
def show[A: Show](a: A) = Show[A].show(a)
implicit class ShowOps[A: Show](a: A) {
def show = Show[A].show(a)
}
implicit val intCanShow: Show[Int] =
new Show[Int] {
override def show(a: Int): String = s"int $a"
}
}
和Main.scala
中:
package com.example
object Main extends App {
println(Show.show(344))
println(30.show)
}
编译器抱怨:
[error] /home/developer/scala/show/src/main/scala/com/example/Main.scala:6:14: value show is not a member of Int
[error] println(30.show)
[error] ^
[error] one error found
我在做什么错了?
答案 0 :(得分:7)
要Main
找到Show
,您需要在import Show._
中的Main.scala
package com.example
object Main extends App {
import Show._
// Or import Show.ShowOps if you only want to use that implicit
println(Show.show(344))
println(30.show)
}
您可以Try it
这里是要记住的implicits rules(摘自Martin的书):
以下是与您的特定案件相关的规则(我已突出显示相关部分):
范围规则:插入的隐式转换必须在范围内,作为 单个标识符,或与该标识符的来源或目标类型相关联 转换。 Scala编译器只会考虑隐式 范围内的转化。进行隐式转换 因此,您必须以某种方式将其纳入范围。 此外,除一个例外,隐式转换必须在范围内 作为单个标识符。编译器将不会插入的转换 形式someVariable.convert。例如,它不会扩展x + y 到someVariable.convert(x)+ y。如果你想 someVariable.convert可作为隐式提供,因此,您将 需要导入它,这将使其可以单个使用 标识符。导入后,编译器可以自由地将其应用为 转换(x)+ y。实际上,图书馆通常会包含一个 前导对象,包括许多有用的隐式转换。 然后,使用该库的代码可以执行一个“导入Preamble._” 访问库的隐式转换
答案 1 :(得分:4)
尝试一下。
package com.example
import Show._ // add in order to access implicit..
object Main extends App {
println(Show.show(344))
println(30.show)
}