【问题标题】:Instantiation of a single trait vs a mixin单个 trait 与 mixin 的实例化
【发布时间】:2019-08-11 14:52:20
【问题描述】:

知道为什么我不能在不提供类主体的情况下创建单个特征的实例:

trait MyTrait
val test1 = new MyTrait // Does not compile.
val test2 = new MyTrait {} // Compiles.

但如果我再添加一个实例,我将能够创建一个实例:

trait MyTrait
trait SecondTrait
val anotherTest = new SecondTrait with MyTrait  // Compiles successfully.

我会期待同样的行为。

旁注:我已经阅读过this question。但是特征体的存在并不能回答我的问题,因为第二个例子仍然没有身体。那么,为什么编译器会认为第二个例子是匿名类呢?

【问题讨论】:

  • 我猜,如果你给MyTrait一个实际的代码体,那么你就不会再有这个问题了。
  • 编辑您的问题以包含完整的特征。
  • @RobertHarvey,代码还可以,您的教程并未声称涵盖所有 scala 功能
  • 第二个有效......这就是问题所在,第二个如何有效(假设您仍然保留第一个特征定义)
  • 哇,这里有很多cmets...不管怎样,看看users.scala-lang.org/t/instantiation-of-traits/3505/4

标签: scala


【解决方案1】:

Instance Creation Expressions 的规范说:

一个简单的实例创建表达式是new c 的形式,其中c 是一个构造函数调用。让T 成为c 的类型。那么T 必须表示scala.AnyRef 的非抽象子类(的类型实例)...

对于某些类模板t,一般实例创建表达式的形式为new t。这样的表达式等价于块{ class a extends t; new a },其中a 是用户程序无法访问的匿名类的新名称。

在new MyTrait 中,MyTrait 在语法上是合法的构造函数调用。所以new MyTrait 是一个简单 实例创建表达式,它无法编译,因为MyTrait 没有“表示scala.AnyRef 的非抽象子类”。

但SecondTrait with MyTrait 不能是构造函数调用,因此它被视为创建匿名类的general 实例创建表达式的类模板。这同样适用于MyTrait {}。

【讨论】:

    猜你喜欢
    • 2011-02-04
    • 2013-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 2015-04-15
    • 2023-03-14
    相关资源
    最近更新 更多