如何使用Scala';什么是单例对象类型?

如何使用Scala';什么是单例对象类型?,scala,types,object,singleton,Scala,Types,Object,Singleton,我正在编写一个类,作为一系列单例对象的基类。在每个单例对象中,都会有表示某些属性的VAL,我想为每个单例对象编写一个方法,该方法只接受由它创建的对象 因此,我有以下几点: class Obj[M <: Maker] class Maker { implicit val me: this.type = this def make[M <: Maker](implicit maker: M) = new Obj[M] def accept(obj: Obj[this.typ

我正在编写一个类,作为一系列单例对象的基类。在每个单例对象中,都会有表示某些属性的VAL,我想为每个单例对象编写一个方法,该方法只接受由它创建的对象

因此,我有以下几点:

class Obj[M <: Maker]

class Maker {
  implicit val me: this.type = this
  def make[M <: Maker](implicit maker: M) = new Obj[M]
  def accept(obj: Obj[this.type]) = {...}
}
但是,如果我尝试这样做:

M.accept(M.a)
然后我得到一个编译时错误:

type mismatch; found : com.test.Obj[object com.test.M] required: com.test.Obj[com.test.M.type]
我的问题是:

  • 对象com.test.M的类型是什么,它与com.test.M.type有何不同
  • 我怎样才能以更聪明的方式做到这一点

  • 使用
    this.type
    而不是
    M
    。这个简化的例子应该适用于:

    class Obj[M <: Maker]
    
    class Maker {
      def make() = new Obj[this.type]
      def accept(obj: Obj[this.type]) = println(obj)
    }
    
    object M extends Maker
    
    object N extends Maker
    
    M.accept(M.make()) //works!
    M.accept(N.make()) //error! type mismatch!
    
    class Obj[M这项工作:

    class Obj[M <: Maker]
    
    class Maker {
      implicit val me: this.type = this
      def make[M <: Maker](implicit maker: M) = new Obj[M]
      def accept(obj: Obj[this.type]) = ()
    }
    
    object M extends Maker {
      val a = make[M.type]
    }
    
    M.accept(M.a)
    
    class Obj[M您的第一个问题,“对象com.test.M
    的类型是什么,它与
    com.test.M.type
    有何不同?”,仍然没有得到回答。我还没有在规范中找到它的文档,但似乎
    对象M
    类型是表示在定义对象
    M
    时隐式创建的类的内部类型。当然,
    M
    是该类的唯一实例,因此人们会期望
    对象M
    类型相当于
    M.type
    ,但编译器显然不这么看

    您遇到的问题是,在调用
    make
    方法时,没有为type参数推断出单例类型
    M.type
    。这与在下面的会话中推断出
    String
    而不是
    v.type
    的原因相同:

    scala> val v = "asdf"                      
    v: java.lang.String = asdf
    
    scala> identity(v)
    res0: java.lang.String  = asdf
    
    其中,
    identity
    定义为

    def identity[T](v: T) = v
    

    跟上时代,我的好朋友!我在24小时前就解决了这个问题。接下来,我希望看到迅猛龙追逐渡渡鸟,一边在pointcast屏幕保护程序上查看股票行情,一边疯狂地挥舞着马车鞭子

    有关承诺是:

    /1130.scala
    
    Obj类[M代表第2点:始终有可能使
    Obj
    成为
    Maker
    的嵌套类,并删除类型参数,但我不希望这样,因为我需要将Obj实例传递给我的示例中类之外的对象,并且我需要对类型参数进行筛选。您能提供一个可编译的示例吗我可以复制并粘贴到REPL吗?好问题:我在实现HList时遇到了同样的问题,HNil的类型被推断为object HNil而不是HNil.type。升级到2.9 nightly build,现在一切都好了。这里的隐式是多余的:它只会迫使M成为this.type…在这种情况下,我们最好使用this.type direc首先,给我们介绍Michel Krämer的解决方案。实际上,我正在努力避免显式的
    [m.type]
    当从
    M
    调用
    make
    时,@Miles:我只是假设他已经轻描淡写了他在这篇文章中的真实案例,但在实际代码中他需要itThanks,这很好。但是为什么我的示例不起作用,我的推理有什么问题吗?
    object com.text.M
    com.tex之间到底有什么区别t、 M.type
    ?很好!所以我认为这肯定是一个编译器错误,而不是我对正在使用的类型的心理表示的问题。好吧,没有人说这是一个错误。这是一个不受欢迎的行为,但它是指定的。很公平,但是在这种情况下,你能向我解释type
    object M
    和type
    M之间的区别吗。键入
    ?在实现之外没有什么意义。从r23624开始,我甚至不知道您将在哪里遇到“对象M”不再:它不是一种你可以表达的类型,所以如果它没有被推断出来,那么它就变成了幕后的类型。这是有道理的。但它似乎在2.9中即兴修复了这个行为,所以要么
    对象M
    真的是
    M.type
    ,并且有一个bug,要么类型推断发生了轻微的变化。如果你在当您编写
    val v=“string”
    时,v作为类型字符串,当您编写
    val singleton=M
    时,singleton具有类型
    M.type
    ,而不是
    对象M
    ,因此我希望我的初始示例能够工作。很高兴它在2.9中能够工作
    def identity[T](v: T) = v
    
    // 1130.scala
    class Obj[M <: Maker]
    
    class Maker {
      implicit val me: this.type = this
      def make[M <: Maker](implicit maker: M) = new Obj[M]
      def accept(obj: Obj[this.type]) = ()
    }
    
    object M extends Maker {
      val a = make
    }
    
    object Test {
      def main(args: Array[String]): Unit = {
        M.accept(M.a)
      }
    }
    
    // too old
    % /scala/inst/scala-2.9.0.r23619/bin/scalac ./1130.scala 
    ./1130.scala:15: error: type mismatch;
     found   : Obj[object M]
     required: Obj[M.type]
        M.accept(M.a)
                   ^
    one error found
    
    // fresh enough
    % /scala/inst/scala-2.9.0.r23624/bin/scalac ./1130.scala 
    %