在Scala工作表中的随播对象中找不到隐式值

时间:2019-09-12 19:10:53

标签: scala intellij-idea typeclass implicit

我正在尝试在IntelliJ Scala工作表中创建一个类型类。所以我从这样的特征开始

trait Show[A] {
  def show(a : A) : String
}

并创建了一个随播对象

object Show {

  def show[A](a: A)(implicit sh: Show[A]) = sh.show(a)

  implicit val intCanShow: Show[Int] =
    new Show[Int] {
      def show(int: Int): String = s"int $int"
    }

}

当我尝试

println(Show.show(20))

我收到此错误。

Error:(50, 26) could not find implicit value for parameter sh: Show[Int]
println(Show.show(20))

但是当我从对象Show中取出intCanShow时,它可以正常工作。为什么不能scala访问对象内部的隐式?

2 个答案:

答案 0 :(得分:1)

隐式解析会尝试伴随对象,因此您的代码看起来还可以。但是,要使对象成为伴侣,它必须满足以下两个requirements

  1. 伴随对象是与类或特征同名的对象,并且
  2. 相同的源文件中定义为关联的类或特征。

以下警告表示不满足第二个要求:

defined object Show
warning: previously defined trait Show is not a companion to object Show.
Companions must be defined together; you may wish to use :paste mode for this.

要满足第二个要求,我们必须在Scala工作表中使用Plain评估模型,或者在Scala REPL中使用:paste模式。

Scala Worksheet Plain评估模型

要在IntelliJ Scala工作表中定义同伴对象,应将Run type更改为Plain

  1. Show Worksheet Settings
  2. 选择标签Settings for *.sc
  3. Run typeREPL更改为Plain

Scala REPL粘贴模式

根据@jwvh的建议,请确保输入paste mode

  

如果类或对象具有同伴,则必须在同一个对象中定义两者   文件。要在REPL中定义随播广告,请在同一位置上定义   行或进入:paste模式。

here所示。

答案 1 :(得分:1)

作为scala脚本运行时,您的示例似乎可以正常工作。
在名为test.sh并标记为可执行文件的文件中包含以下内容

#!/usr/bin/env scala
trait Show[A] {
  def show(a : A) : String
}
object Show {
  def show[A](a: A)(implicit sh: Show[A]) = sh.show(a)

  implicit val intCanShow: Show[Int] =
    new Show[Int] {
      def show(int: Int): String = s"int $int"
    }
}

println(Show.show(20))

我观察

bash-3.2$ ./test.sh
int 20