我需要使用一个类型(任何类型)作为隐式的标记作为类型参数,以区别于另一个隐式。这很奇怪,但这可能是另一个问题。
由于我可以使用任何类型,我想在内存占用和初始化时间方面使用最便宜的类型。在这种情况下,它可能不会对性能造成太大影响,但问题很有趣:Scala最便宜的哪一种?
在Java中,答案显然是java.lang.Object
。但是Scala有一些“有趣”的类型:Any
,AnyVal
类型,以及可能围绕它们进行优化的底层类型。 Nothing
类型无法实例化,因此会从此比较中排除。
答案 0 :(得分:13)
这取决于你的确切问题,但Scala中最便宜的构造 - 或任何语言 - 必须是一个根本不存在的构造......(至少,不是在运行时)
请允许我介绍Phantom Types,允许编译器静态地执行正确的操作,但在它们到达JVM之前会被删除为虚无。
类似地,您可以轻松区分两个不同类型的对象,而无需任何标记字段。这是case object
的一个很好的候选者,并且与模式匹配非常相似。
答案 1 :(得分:4)
我不确定我用“最便宜的类型”得到你的意思...在Java中,最便宜的数值类型在内存方面可以是字节,但是从性能POV Java优化到工作用int。事实上,许多(或大多数)语言都经过优化,可以使用int(甚至是DB引擎)。 Scala是JVM语言,所以我想说最好使用int。
更新:如果问题是“标记/未标记”合适的数据类型,我会使用布尔基元。
如果在Scala中键入boolean 程序,你实际得到的类型 是scala.Boolean。或者如果你输入 浮动,你会得到scala.Float。什么时候 您将Scala代码编译为Java 但是,字节码,Scala会编译 这些类型是Java的原始类型 在哪里可以获得性能 Java原始类型的好处。
没有什么是Any,它是Java中的一种Object,任何Object都需要比任何原始类型更多的内存
顺便说一下,使用布尔值作为标记是很自然的,它可以提高代码的可读性(从而提高支持度,让别人理解)。即使还有其他任何东西,更优化的我也不会做过早优化,而是选择布尔值。
答案 2 :(得分:3)
如果您选择Any
或AnyVal
,那么您传递的任何原语都会被装箱,因此可能已经过了。
AnyRef
确实是一个不错的选择。
如果没有任何类型参数化,那么“原语”也是不错的选择 - 例如Boolean
或Int
。
还有Null
,这是一个非常有趣的选择,因为它根本不分配任何东西,而且它是一个文字,所以它必然是快速的。我不知道你究竟在做什么,我不知道这是否是有效的选择。
另一个有趣的选项是java.lang.Integer
(使用静态方法valueOf
),因为它保证了小值的引用相等性(你必须检查文档以查看精确范围是什么),意思是没有分配。
答案 3 :(得分:1)
由于Scala运行在Java之上,我认为相同的答案也适用于Scala世界。 Any类型的Scala对象只是某种Java对象。
在Java中我认为像int,short或byte这样的原始类型比Object便宜,但是这些类型可能在Scala中被包装/装箱。 (虽然不是100%肯定。)
<强>更新强>
如果由于某种原因它必须是一个对象而不是一个原始类型,String可能是最好的,因为字符串是在VM中实现的。因此在整个应用程序中通常只有一个对象实例。
答案 4 :(得分:0)
当您运行包装器的方法调用时,Scala会包装基本类型,而基本类型不会实现。所以即。 1024 * 512未包装但在1024.toInt * 512中1024被包装。