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

scala – 抽象类型与类型参数

发布时间:2020-12-16 09:36:42 所属栏目:安全 来源:网络整理
导读:抽象类型在什么情况下优于类型参数? 解决方法 要添加到我的 previous answer on Abstract type vs. parameters,你也有 JESSE EICHAR’s recent blog post(2010,5月3日)突出显示一些关键的区别: trait C1[A] { def get : A def doit(a:A):A}trait C2 { ty
抽象类型在什么情况下优于类型参数?

解决方法

要添加到我的 previous answer on Abstract type vs. parameters,你也有 JESSE EICHAR’s recent blog post(2010,5月3日)突出显示一些关键的区别:

trait C1[A] {
  def get : A
  def doit(a:A):A
}
trait C2 {
  type A
  def get : A
  def doit(a:A):A
}

在C2情况下,参数为“埋”(作为内部抽象类型)。
(除了这个缩写,它实际上并没有被掩埋,见下文)

而通用类型,明确地提到了参数,帮助其他表达式知道他们应该使用什么类型

所以(C1:参数):

//compiles
def p(c:C1[Int]) = c.doit(c.get)

它编译,但是您明确公开您要使用的“A”类型。

和(C2:抽象类型):

// doesn't compile
def p2(c:C2) = c.doit(c.get)
<console>:6: error: illegal dependent method type
       def p2(c:C2) = c.doit(c.get)
              ^

它不编译,因为p2定义中没有提到’A’,所以doit在编译类型中不知道应该返回什么。

当使用抽象类型并希望避免对接口的任何“类型泄漏”(即,想要公开“A”实际上是什么)时,可以指定非常通用的类型作为p2的返回值:

// compiles because the internals of C2 does not leak out
def p(c:C2):Unit = c.doit(c.get)

或者您可以直接在doit函数中“修复”该类型
def doit(a:A):Int而不是def doit(a:A):A,这意味着:
def p2(c:C2)= c.doit(c.get)将编译(即使p2没有提到任何返回类型)

最后(retronym的评论),您可以通过细化C2抽象参数明确指定A:

scala> def p2(c:C2 { type A = Int }): Int = c.doit(c.get)
p2: (c: C2{type A = Int})Int

或者通过添加一个类型参数(并用它来提炼C2抽象类型!)

scala> def p2[X](c:C2 { type A = X }): X = c.doit(c.get)
p2: [X](c: C2{type A = X})X

所以推荐抽象:

>当您想从客户端代码中隐藏类型成员的确切定义时,请使用像C2中的抽象类型(但要谨慎使用C2定义函数)
>如果要在C2的子类中协方差地重写该类型,请使用抽象类型(带有限类型抽象)
>当您想通过traits混合这些C2类型的定义时,使用抽象类型(当您将C2与您的班级混合时,您不会有“A”处理:您只混合C2)

对于需要简单类型实例化的其余部分,请使用参数。
(如果你知道不需要扩展名,但你仍然需要处理几种类型:这就是参数类型)

retronym补充说:

主要的区别是

>方差:C2只能在A中不变,
>类型成员可以在子类型中选择性覆盖的方式(而类型参数必须重新声明并传递给超类型)

(如illustrating here:

trait T1 {
  type t
  val v: t
}
trait T2 extends T1 {
  type t <: SomeType1
}
trait T3 extends T2 {
  type t <: SomeType2  // where SomeType2 <: SomeType1
}
class C extends T3 {
  type t = Concrete    // where Concrete <: SomeType2
  val v = new Concrete(...)
}

)

(编辑:李大同)

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

    推荐文章
      热点阅读