代码之家  ›  专栏  ›  技术社区  ›  Thomas Jung

具有抽象类型成员的具体类

  •  6
  • Thomas Jung  · 技术社区  · 15 年前

    考虑到以下特点和阶级。为什么要编译?这个真的可以用来做什么吗?

    trait Container {
      type A
    }
    
    trait AnotherContainer[B]{
        def x(b : B) : B
    }
    
    trait Mixed extends Container with AnotherContainer[Container#A]
    
    class Impl extends Mixed{
        def x(a : Container#A) = a 
    }
    
    new Impl().x _
    
    scala> new Impl().x _
    res0: (Container#A) => Container#A = <function>
    

    更新:

    class Baz { type T; }
    

    实际上是一个特性,但我找不到它的动机: #1753 .

    2 回复  |  直到 15 年前
        1
  •  2
  •   Rex Kerr    15 年前

    如果对我没用的话,它看起来是无害的。X想要的类型不存在,因此无法将其传递给方法。我想,无害的无用性是否应该是编译时的错误,这是个问题。

    如果你看一下x实际上做了什么,它会反编译为:

    public java.lang.Object x(java.lang.Object);
      Code:
       0:   aload_1
       1:   areturn
    

    这正是Identity方法应该做的(加载参数,不管类型如何,返回它)。你可以用更少的代码编写类似的代码:

    trait AbstractType { type T }
    class Useless extends AbstractType { def identity(t: AbstractType#T) = t }
    

    除了类型abstracttype t之外,没有其他内容,因此我们也没有用处。

    除非我错过了什么。

        2
  •  3
  •   retronym    15 年前

    在您的示例中,编译器添加了 >: Nothing <: Any .下面的第二个示例显示了一个抽象类型变得可用(如果不可用)的情况。

    scala> trait T { type A >: Nothing <: Any }
    defined trait T
    
    scala> 1: T#A
    <console>:6: error: type mismatch;
     found   : Int(1)
     required: T#A
           1: T#A
           ^
    
    scala> trait T { type A >: Int <: Int }
    defined trait T
    
    scala> 1: T#A                          
    res6: T#A = 1
    
    scala> "": T#A
    <console>:6: error: type mismatch;
     found   : java.lang.String("")
     required: T#A
           "": T#A
           ^