【问题标题】:structural type extending another structural type结构类型扩展另一种结构类型
【发布时间】:2020-12-30 13:22:52
【问题描述】:

为什么以下是不允许的? (2.12):

type Foo <: {def foo(): Unit}
type Bar <: {def bar(): Unit} with Foo

在我看来很自然,Bar 应该同时具有 foo()bar()

【问题讨论】:

标签: scala types structural-typing compound-type


【解决方案1】:

似乎可以使用括号

scala> type Foo <: {def foo(): Unit}
     | type Bar <: ({def bar(): Unit}) with Foo
type Foo
type Bar

【讨论】:

    【解决方案2】:

    type Foo &lt;: {def foo(): Unit}type Foo &lt;: AnyRef{def foo(): Unit}

    所以虽然 type Bar &lt;: {def bar(): Unit} with Foo 不可解析,但 AnyRef 和不同的顺序可以工作

    type Foo <: {def foo(): Unit}
    type Bar <: Foo with AnyRef{def bar(): Unit}
    
    val b: Bar = ???
    b.foo()
    b.bar()
    

    也可以使用括号(和直接命令)

    type Foo <: {def foo(): Unit}
    type Bar <: ({def bar(): Unit}) with Foo 
    
    val b: Bar = ???
    b.foo()
    b.bar()
    

    实际上type Bar &lt;: {def bar(): Unit} with Foo 违反规范,而type Bar &lt;: ({def bar(): Unit}) with Foo 满足规范,因为{def bar(): Unit} 不是SimpleType,但({def bar(): Unit})SimpleType

    CompoundType    ::=  AnnotType {‘with’ AnnotType} [Refinement]
                      |  Refinement
    
    AnnotType       ::=  SimpleType {Annotation}
    
    SimpleType      ::= ............
                      |  ‘(’ Types ‘)’
    
    Types           ::=  Type {‘,’ Type}
    
    Type            ::=  ...........
                      |  CompoundType
                      |  ...........
    

    https://scala-lang.org/files/archive/spec/2.13/03-types.html#compound-types

    【讨论】:

      【解决方案3】:

      规范不允许这样做,它将{ ...} 部分称为可能都有 with 子句的改进。不过反过来也不错。

      这当然有点重复,因为它没有说明为什么规范不允许这样做。这里似乎没有深入的理解,只是这不是你被允许编写类型的方式。您应该能够以另一种方式表达相同的意图。

      【讨论】:

      • 为什么您认为规范不允许这样做? scala-lang.org/files/archive/spec/2.13/…CompoundType ::= AnnotType {‘with’ AnnotType} [Refinement] | Refinement。这里{def bar(): Unit}FooAnnotTypes,Refinement是空的。
      • @DmytroMitin AnnotTypeSimpleType {Annotation}{def bar(): Unit} 不是 SimpleType
      • 对,{def bar(): Unit} 不是SimpleType,但({def bar(): Unit})SimpleType
      • 是@DmytroMitin 吗?编译器接受它就好像它是一样的,但我无法从规范中弄清楚它是如何工作的
      • 是的。 SimpleType ::= SimpleType TypeArgs | SimpleType ‘#’ id | StableId | Path ‘.’ ‘type’ | Literal | ‘(’ Types ‘)’。最后一部分很重要,如果你用括号括起来Types,那么你会得到一个SimpleTypeTypes ::= Type {‘,’ Type},所以一个Type 也是Types{def bar(): Unit} 是一个Type(实际上是一个CompoundType 由单个Refinement 组成),所以({def bar(): Unit}) 是一个SimpleType
      猜你喜欢
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 2018-06-04
      • 2018-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多