如何使用Scala';什么是单例对象类型?
我正在编写一个类,作为一系列单例对象的基类。在每个单例对象中,都会有表示某些属性的VAL,我想为每个单例对象编写一个方法,该方法只接受由它创建的对象 因此,我有以下几点:如何使用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
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]
我的问题是:
使用
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
?很好!所以我认为这肯定是一个编译器错误,而不是我对正在使用的类型的心理表示的问题。好吧,没有人说这是一个错误。这是一个不受欢迎的行为,但它是指定的。很公平,但是在这种情况下,你能向我解释typeobject M
和typeM之间的区别吗。键入
?在实现之外没有什么意义。从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
%