加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 存在类型和类型成员

发布时间:2020-12-16 09:03:33 所属栏目:安全 来源:网络整理
导读:什么工作(A部分) 假设我有一个类型参数的特征: trait A[T] 我可以使用一个存在类型来编写一个将收集的方法,因为它们都具有相同的T: def foo(as: Seq[A[X]] forSome { type X }) = true 请注意,这与以下不同: def otherFoo(as: Seq[A[X] forSome { type X
什么工作(A部分)

假设我有一个类型参数的特征:

trait A[T]

我可以使用一个存在类型来编写一个将收集的方法,因为它们都具有相同的T:

def foo(as: Seq[A[X]] forSome { type X }) = true

请注意,这与以下不同:

def otherFoo(as: Seq[A[X] forSome { type X }]) = true

或相当于:

def otherFoo(as: Seq[A[_]]) = true

在这些情况下,存在的范围在Seq内,所以As可以有不同的Ts.有了我原来的foo(在Seq的存在范围上),以下是很好的:

foo(Seq(new A[Int] {},new A[Int] {}))

但是使类型参数不同,它不会编译:

scala> foo(Seq(new A[Int] {},new A[String] {}))
<console>:10: error: type mismatch;
 found   : Seq[A[_ >: java.lang.String with Int]]
 required: Seq[A[X]] forSome { type X }

              foo(Seq(new A[Int] {},new A[String] {}))
                     ^

这一切都很简单.

什么工作(B部分)

现在假设我有一个类型的成员,而不是一个类型参数:

trait B { type T }

我可以写一个方法,只能使用一些指定的T:

scala> def bar[X](b: B { type T = X }) = true
bar: [X](b: B{type T = X})Boolean

scala> bar[Int](new B { type T = Int })
res5: Boolean = true

scala> bar[String](new B { type T = Int })
<console>:10: error: type mismatch;
 found   : java.lang.Object with B
 required: B{type T = String}
              bar[String](new B { type T = Int })
                          ^

再次,这是完全符合你期望的方式.

什么不行

当我们尝试写相当于我们上面的foo,但对于类型成员,事情变得奇怪.

scala> def baz(bs: Seq[B { type T = X }] forSome { type X }) = true
baz: (as: Seq[B{type T = X}] forSome { type X })Boolean

scala> baz(Seq(new B { type T = Int },new B { type T = String }))
res7: Boolean = true

最后一行编译对我来说没有意义.我已经告诉我,我想让所有的类型成员是一样的.我的foo显示我可以为类型参数执行此操作,而bar显示可以基于类型成员约束类型.但我不能结合这两个.

我在2.9.2和2.10.0-M5上试了一下.

动机

这个问题的灵感来自this one,在那里我的第一个想法是,哦,只是使用一种存在的类型(将这个可以在这里使用的it seems to be impossible to get an existential type to scope of the type of a repeated parameter的问题放在一边):

def accept(rs: Seq[RList[Int] { type S = X }] forSome { type X }) = true

但是这并没有真正的工作 – 你得到与上面简化例子相同的奇怪的结果.

解决方法

我终于明白了(至少我希望如此).我们来做另一回事.我们建立我们的特质:

scala> trait B {type T}
defined trait B

我们尝试建立一个B序列:

scala> Seq(new B {type T = Int},new B {type T = String})
res0: Seq[B{type T >: String with Int}] = List($anon$1@592b12d,$anon$2@61ae0436)

死了,它的作品!好的,我们没有类型T的平等,但让我们玩它:

scala> res0 : (Seq[B {type T = X}] forSome {type X >: String with Int})
res1: Seq[B{type T = X}] forSome { type X >: String with Int } = List($anon$1@592b12d,$anon$2@61ae0436)

更接近不要等等,这并不紧密,比你提出的baz参数要好,我们不仅提供了一个原始类型,还有一个上限!因此,我们可以明确地将其传递给巴兹.这就是为什么它不按预期工作.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读