首页 > 解决方案 > 如何在 Scala 中正确使用存在(forSome)用例的类型定义来表达自引用类型

问题描述

由于两个 scala 编译器限制,我遇到了问题

  1. 在您想要编写实现需要构造具体类型的常见行为的特征的情况下,不可能引用 this 的类型(this.type 不是出于 obv 原因)。解决此问题的推荐模式是

    trait Foo[SelfType <: Foo[SelfType]] {      
       this: SelfType =>   
        final def foo: SelfType = newInstance(??? /*do some work*/)
        protected def newInstance(i: Int): SelfType
    }
    
  2. Scala 编译器(在 Dotty AFAIK 中已修复)不跟踪存在类型的界限(我发现至少 3 个从 2009 年及以后的 scala github 项目中提交的错误)。这意味着,给定上述类型,如果我要编写一个采用某些未知 Foo 的方法

    def process(f: Foo[_])
    

在某些情况下,我可能会遇到一些奇怪的错误编译器行为。相反,我需要手动向编译器表示 _ 此处遵循类型边界以解决其限制。为此,我需要做类似的事情

   def process[F <: Foo[F]](f: Foo[F])

并调用该方法而不传递任何希望正确捕获的类型参数。但是,如果 Foo 采用其他类型的参数,这会使 def 签名变得非常麻烦,从而给客户端带来很多负担。所以我的问题是,是否可以使用类型定义作为正确表达这种自引用类型的简写。例如,我尝试了各种各样的事情。

   type SomeFoo = Foo[SelfType] with SelfType forSome { type SelfType <: Foo[SelfType] } 

但这似乎并没有做到这一点。不知何故,编译器没有意识到 SelfType 是相同的未知类型 SomeFoo。

我希望这是有道理的。谢谢你的帮助。PS随时建议重命名问题,因为现在还不是很清楚。

标签: scalagenericsexistential-type

解决方案


推荐阅读