如果我的“扩展 AnyVal",我应该使用类型吗?有没有方法? [英] Should I use type, if my "extends AnyVal" has not methods?

查看:29
本文介绍了如果我的“扩展 AnyVal",我应该使用类型吗?有没有方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

互联网还不能回答我的问题.这两行对我来说似乎可以互换:

The internet was not able to answer my question yet. Those two lines seem interchangeable to me:

type Meter = Double
class Meter(val d: Double) extends AnyVal

如果 Meter 没有任何方法,我应该使用 type 代替吗?有什么区别?

If Meter does not have any methods, should I use type instead? What's the difference?

推荐答案

有什么区别?

嗯,显而易见的是,第一个只是一个类型别名,仅此而已.后者将尝试展开包装类并直接使用底层原语.但是,在某些情况下 AnyVal 无法解包,它们是 在文档中说明.例如,假设您想将 Meter 传递给多态函数:

Well, the obvious thing is that the first is simply a type alias, nothing more. The latter will attempt to unroll the wrapping class and use the underlying primitive directly. But, there are cases where AnyVal can't be unwrapped which are stated in the documentation. For example, assume you wanted to pass Meter to a polymorphic function:

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

传入 Meter 会分配一个实例:

Passing Meter in would allocate an instance:

scala> class Meter(val d: Double) extends AnyVal
defined class Meter

scala> def identity[T](t: T): T = t
identity: [T](t: T)T

scala> :se -Xprint:typer

scala> identity(new Meter(1.0))

// Shortened this for brevity

private[this] val res0: Meter = $line4.$read.$iw.$iw.identity[Meter](new $line3.$read.$iw.$iw.Meter(1.0));
<stable> <accessor> def res0: Meter = $iw.this.res0

另一方面,type Meter 总是会产生 Double:

On the other hand, type Meter will always yield a Double:

scala> type Meter = Double
defined type alias Meter

scala> val m: Meter = 1.0
m: Meter = 1.0

scala> def identity[T](t: T): T = t
identity: [T](t: T)T

scala> :se -Xprint:uncurry

scala> identity(m)
private[this] val res1: Double = $line5.$read.$iw.$iw.identity[Double]($line4.$read.$iw.$iw.m());
<stable> <accessor> def res1(): Double = $iw.this.res1

另一个敏感点是,如果您分配一个Array[Meter],则需要分配一个实例.

Another sensitivity is that if you allocate an Array[Meter], an instance will need to be allocated.

两者之间存在差异.你应该使用哪一个?通常,这取决于.如果类型安全对您来说非常重要,并且您不介意发生额外分配的边缘情况,请使用该类.如果你有一个相当复杂的类型想要抽象,例如一个 Either[String, A],你想让类型更简单,也许一个 type Foo[A] = Each[String, A] 会更容易理解,也更直观.

There are differences between the two. Which one should you use? As usually, it depends. If type safety is of outter importance to you and you don't mind the edge cases where one occurs an extra allocation, go with the class. If you have a rather complex type you want to abstract over, for example a Either[String, A] where you want to make the type simpler, perhaps a type Foo[A] = Either[String, A] would be simpler to understand and more intuitive.

这篇关于如果我的“扩展 AnyVal",我应该使用类型吗?有没有方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆