Scala 2.10引入了值类.它们对于编写类型安全代码非常有用.此外还有一些限制,其中一些将由编译器检测,有些则需要在运行时进行分配.
我想使用case class语法创建值类,以允许创建 - 无需新语法和人性化toString.没有模式匹配,因为它需要分配.
所以问题是:将使用case class语法需要值类分配吗?
Rüd*_*ehn 34
您可以拥有一个值类的案例类.从下面的示例中可以看出,没有对象创建.除了当然不可避免的拳击,如果你会向上倾向任何.
这是一小段scala代码
class ValueClass(val value:Int) extends AnyVal
case class ValueCaseClass(value:Int) extends AnyVal
class ValueClassTest {
var x: ValueClass = new ValueClass(1)
var y: ValueCaseClass = ValueCaseClass(2)
def m1(x:ValueClass) = x.value
def m2(x:ValueCaseClass) = x.value
}
Run Code Online (Sandbox Code Playgroud)
字节码,不包含两个值类的最轻微的痕迹.
Compiled from "ValueClassTest.scala"
public class ValueClassTest {
public int x();
Code:
0: aload_0
1: getfield #14 // Field x:I
4: ireturn
public void x_$eq(int);
Code:
0: aload_0
1: iload_1
2: putfield #14 // Field x:I
5: return
public int y();
Code:
0: aload_0
1: getfield #21 // Field y:I
4: ireturn
public void y_$eq(int);
Code:
0: aload_0
1: iload_1
2: putfield #21 // Field y:I
5: return
public int m1(int);
Code:
0: iload_1
1: ireturn
public int m2(int);
Code:
0: iload_1
1: ireturn
public rklaehn.ValueClassTest();
Code:
0: aload_0
1: invokespecial #29 // Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_1
6: putfield #14 // Field x:I
9: aload_0
10: iconst_2
11: putfield #21 // Field y:I
14: return
}
Run Code Online (Sandbox Code Playgroud)
为了扩展这个问题,Wojciech Langiewicz提出了一个用作案例类的Value类的一个很好的例子.
代替:
case class Player(id: Int, gameCash: Int, gameCoins: Int, energy: Int)
Run Code Online (Sandbox Code Playgroud)
Wojciech定义:
case class Player(id: PlayerId, gameCash: GameCash, gameCoins: GameCoins, energy: Energy)
Run Code Online (Sandbox Code Playgroud)
使用case类(不在堆上分配其他对象):
case class PlayerId(id: Int) extends AnyVal
case class GameCash(value: Int) extends AnyVal
case class GameCoins(value: Int) extends AnyVal
case class Energy(value: Int) extends AnyVal
Run Code Online (Sandbox Code Playgroud)
在创建只包含一个参数的case类时,你应该添加它
extends AnyVal以允许Scala编译器运行更多优化 - 基本上类型检查只在编译阶段完成,但在运行时只会创建底层类型的对象,这会导致更少的内存开销.在我们的代码中的特定点添加自定义类型不仅提高了可读性,而且还允许我们减少错误 - 卸载一些检查,否则这些检查必须在测试中完成(或者根本不需要).您还可以立即在IDE或编辑器中看到错误.
因为现在类中的每个组件
Player本身都是一个单独的类型,所以添加新的操作符也很容易,否则可能必须隐式添加这些操作符会污染更大的范围.