【发布时间】:2012-07-21 18:29:41
【问题描述】:
无论明智与否,我正在编写一个我想只接受 Scala 单例的方法,即通过“对象”实现的对象,而不是类或特征的构造实例。它应该接受任何类型的 Scala 单例,因此“MySingleton.type”不会这样做。
我遇到了非常奇怪的构造“scala.Singleton”,它没有在 api 文档中记录,但似乎可以解决问题:
scala> def check( obj : Singleton ) = obj
check: (obj: Singleton)Singleton
scala> check( Predef )
res0: Singleton = scala.Predef$@4d3e9963
scala> check ( new java.lang.Object() )
<console>:9: error: type mismatch;
found : java.lang.Object
required: Singleton
check ( new java.lang.Object() )
scala> check( Map )
res3: Singleton = scala.collection.immutable.Map$@6808aa2d
scala> check( Map.empty[Any,Any] )
<console>:9: error: type mismatch;
found : scala.collection.immutable.Map[Any,Any]
required: Singleton
check( Map.empty[Any,Any] )
然而,相当莫名其妙(对我来说),字符串文字被接受为单例,而显式构造的字符串不是:
scala> check( "foo" )
res7: Singleton = foo
scala> check( new String("foo") )
<console>:9: error: type mismatch;
found : java.lang.String
required: Singleton
check( new String("foo") )
为什么字符串字面量符合 Singleton?我是否误解了 Singleton 类型应该指定的内容?
【问题讨论】:
-
我不是很肯定,但我相信这是因为编译器默认实习他们。
-
我第一次听说
scala.Singleton,它不在文档中。我不会打赌它会做出任何特别的承诺。事实上,我不确定是否有任何硬性标准可以用来区分单例对象和类。你能详细说明你通过识别它们来达到什么目标吗? -
(我的动机相当微不足道:我希望能够导出 Java 转发类的完全限定名称,因此我可以通过 Java 反射将单例方法用作静态方法。我不喜欢依赖重整/美元签名的名称,因为它们可能会改变。所以,我编写了一个实用程序,将单例类名称取消标记为 Scala 为 Java 提供的名称。如果重整改变,我只需要更新我的方法。方法是仅适用于 Scala 单例,因此如果类型系统能够强制执行它,我希望它在获取和分解类名之前需要一个单例。)
-
顺便说一句,Scala 2.10 将提供一个反射 API 来提供帮助。
-
您可能想知道
check(1)也有效。似乎所有原始值都被视为单例。check(Double.NegativeInfinity)也可以。
标签: scala