scala 中上下文参数的 "with" 和 "new" 有什么区别?

What is the difference between "with" and "new" for context parameters in scala?

如果我使用关键字 with 或使用 new 为上下文参数定义 given 值,是否有区别?

例如 humancat given 之间有区别吗?

 trait Talker:
  def talk:String

given human:Talker with
  def talk:String = "I am human"

given cat:Talker = new:
  def talk:String = "I am cat, meow"

def run(using t:Talker):Unit =
  println(t.talk)

使用 newwith 时编译的 class 级别存在明显差异。

在使用with时,创建了一个专用的class,我们可以在de-compiled代码中看到。这是它在 Java

中的样子
public final class Talker$package {
   public static final class human$ implements Talker, Serializable {
      public static final Talker$package.human$ MODULE$ = new Talker$package.human$();

      private Object writeReplace() {
         return new ModuleSerializationProxy(Talker$package.human$.class);
      }

      public String talk() {
         return "I am human";
      }
   }
}

它有一个专用的 class human$ 扩展 Talker

另一方面,当 new 用于 cat 时,我们有一个匿名的 class。

public final class Talker$package {
   public static Talker cat() {
      return Talker$package$.MODULE$.cat();
   }
}

其中 MODULE$.cat() 最终指向以下

Talker var5 = new Talker() {
    public String talk() {
       return "I am cat, meow";
    }
};