Scala-为什么不能从对象使用trait

Scala-为什么不能从对象使用trait,scala,Scala,我用singleton对象创建了一个简单的应用程序,其中包含本地特性: object Singleton { trait FirstTrait { val func1 = (i: Int) => i * 2 } trait SecondTrait { val func2 = (s: String) => s } trait ThirdTrait { val func3 = () => println("Func 3") }

我用singleton对象创建了一个简单的应用程序,其中包含本地特性:

object Singleton {

  trait FirstTrait {
    val func1 = (i: Int) => i * 2
  }

  trait SecondTrait {
    val func2 = (s: String) => s
  }

  trait ThirdTrait {
    val func3 = () => println("Func 3")
  }
}
现在,在
Main
object中,我想做如下操作:

object Main extends App {    
  val singleton = Singleton.FirstTrait//cannot do this
}
但我不能这样做(编译错误)。为什么?为什么我不能接触到这种地方特征?如果我将
Singleton
对象更改为:

object Singleton {

  trait FirstTrait {
    val func1 = (i: Int) => i * 2
  }

  trait SecondTrait {
    val func2 = (s: String) => s
  }

  trait ThirdTrait {
    val func3 = () => println("Func 3")
  }

  object FirstObject extends FirstTrait {
    println(func1)
  }
}
Main
运行良好,程序可编译。但是我从
singleton
调用另一个singleton对象,而不是trait。我知道不能实例化
trait
,但我认为这不是一个解决方案,因为我还有一个简单的
ScalaTest
测试名称,它看起来像

"Singleton" should "test it" in Singleton.FirstTrait{...}
在这里,我可以访问
FirstTrait
。那么为什么我不能在普通代码中使用它呢?
我不能很好地理解它。也许我是个白痴,但如果有人能给我解释清楚的话,我会很高兴的

这是一种
特征
,因此您需要正确地“实例化”它:

val singleton = new Singleton.FirstTrait {}
// singleton: Singleton.FirstTrait = $anon$1@5e97da56

请注意,从技术上讲,
trait
不能实例化。上面的表达式是扩展trait的匿名类的实例化。

它是一个
trait
,因此您需要正确地“实例化”它:

val singleton = new Singleton.FirstTrait {}
// singleton: Singleton.FirstTrait = $anon$1@5e97da56

请注意,从技术上讲,
trait
不能实例化。上面的表达式是扩展trait的匿名类的实例化。

Singleton。FirstTrait
是一个类型,而不是一个值。你不会写字

val singleton = Singleton.FirstTrait
比你能写的还要多吗

val singleton = Int
val singleton = String
等。trait和类可以有同伴对象(
object
s同名),但是
FirstTrait
显然没有

你可以用它作为一种类型,例如

def foo(x: Singleton.FirstTrait) = {}
val x: Singleton.FirstTrait = new Singleton.FirstTrait {}

Singleton.FirstTrait
是一个类型,而不是一个值。你不会写字

val singleton = Singleton.FirstTrait
比你能写的还要多吗

val singleton = Int
val singleton = String
等。trait和类可以有同伴对象(
object
s同名),但是
FirstTrait
显然没有

你可以用它作为一种类型,例如

def foo(x: Singleton.FirstTrait) = {}
val x: Singleton.FirstTrait = new Singleton.FirstTrait {}

好的,我明白了。所以在Scala中,
特征
可以像普通的
一样实例化<代码>新建关键字和
对象
合二为一对我来说不符合逻辑。你能说得更多吗?没错,因为这是一个
特征
,你需要实现它的抽象成员(如果有的话)。这是一个可能会引起兴趣的相关问题。不完全是,这不是实例化该特性,而是一个扩展该特性的匿名类。@Alexey Romanov,说得好。这确实是一个匿名类的实例,它扩展了这个特性。所以在Scala中,
特征
可以像普通的
一样实例化<代码>新建关键字和
对象
合二为一对我来说不符合逻辑。你能说得更多吗?没错,因为这是一个
特征
,你需要实现它的抽象成员(如果有的话)。这是一个可能会引起兴趣的相关问题。不完全是,这不是实例化该特性,而是一个扩展该特性的匿名类。@Alexey Romanov,说得好。这确实是一个匿名类的实例,它扩展了这个特性。在我的第二个例子中,我有一个
trait
的伴生对象,所以我可以像使用值一样使用它。它只是一个对象(不是伴生对象,因为它被称为
FirstObject
,而不是
FirstTrait
),你可以使用任何对象作为值。好的,我知道了。在我的第二个例子中,我有一个
trait
的伴生对象,所以我可以像使用值一样使用它。它只是一个对象(不是伴生对象,因为它被称为
FirstObject
,而不是
FirstTrait
),您可以使用任何对象作为值。