复合类型的意外行为 [英] Unexpected behavior with compound types

查看:56
本文介绍了复合类型的意外行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有3个特点

  trait A
  trait B
  trait AB extends A with B

和方法

def collect[E: Manifest](list: List[Any]) =
    list flatMap {
      case record: E => Some(record)
      case _         => None
    }

对于给定的列表

val list = new A {} :: new A {} :: new A with B {} :: new AB {} :: Nil

我用不同的类型调用了collect

collect[A with B](list) // collect all elements from the list
collect[AB](list) // collect only the last element

谁能解释A with BAB 类型的行为差异?

Could anyone explain the difference in behavior for A with B and AB types?

推荐答案

非常不直观,但符合规范.首先,引用 Manifest 文档(强调我的):

It is highly unintuitive but it conforms to the specification. First, quoting from the Manifest docs (emphasis mine):

Manifest[T] 是类型 T 的不透明描述符.它支持的用途是允许访问类型的擦除

A Manifest[T] is an opaque descriptor for type T. Its supported use is to give access to the erasure of the type

所以在collect[A with B]中,我们匹配A with B擦除.那是什么?如果我们查看 类型擦除 部分,我们阅读:

So in collect[A with B] we are matching the erasure of A with B. And what is that? if we look at the Type erasure section of the spec, we read:

复合类型T1 with ... with Tn的擦除是对T1, ..., Tn的交集支配项的擦除

The erasure of a compound type T1 with ... with Tn is the erasure of the intersection dominator of T1, ..., Tn

交集支配者被定义为(再次强调我的)

and the intersection dominator is defined as (again, emphasis mine)

类型列表 T1, ..., Tn 的交集支配子计算如下.让 Ti1, ..., Tim 是类型 Ti 的子序列,这些类型不是其他类型 Tj 的超类型.如果这个子序列包含一个类型指示符Tc,它指的是一个不是特征的类,则交集支配者是Tc.否则,交集支配者是子序列的第一个元素Ti1

The intersection dominator of a list of types T1, ..., Tn is computed as follows. Let Ti1, ..., Tim be the subsequence of types Ti which are not supertypes of some other type Tj. If this subsequence contains a type designator Tc that refers to a class which is not a trait, the intersection dominator is Tc. Otherwise, the intersection dominator is the first element of the subsequence, Ti1

在我们的例子中,子序列是 A,B 因为它们没有任何子类型关系,因此 A with B 的擦除是 A,所以在 collect[A with B] 中,我们实际上匹配了 A.

In our case the subsequence is A,B as they don't have any subtyping relationship, and thus the erasure of A with B is A, so that in collect[A with B] we are actually matching A.

您可以通过查看 collect[B with A] 的输出和/或向您的 添加 new B {} 的输出来轻松查看此行为列表.

You can easily see this behavior by looking at the output of collect[B with A], and/or adding a new B {} to your list.

这篇关于复合类型的意外行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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