【问题标题】:Scala: Extract types from generic parametersScala:从泛型参数中提取类型
【发布时间】:2014-03-08 08:14:17
【问题描述】:

我有这样的课:

abstract class Foo[I, T, A <: Bar[I, T]](x: SomeClass[A]){

当我想继承类 Foo 时,我必须指定类型 T 和 I,它们可以从类型 A 的类型参数中提取。(即有足够的数据来提取这些类型。) Scala 编译器是否允许以某种方式提取它们?我想写一些类似的东西:

abstract class Foo[A <: Bar[_, _]](x: SomeClass[A]){
    type Bar[I, T] = A    // <-- something like pattern matching

很奇怪,我可以这样写,但type Bar[I, T] = A 行似乎没有声明任何内容。该行通过了,但我既不能使用I,也不能使用T

我可以做类似的事情吗?

我知道我可以使用abstract class Foo[I, T](x: SomeClass[A]){,然后定义type A = Bar[I, T],但它失去了一些普遍性。此外,这种情况对于代码用户来说意味着更多(样板)代码,因为他们可能会为Bar[I, T] 定义一个快捷方式(即类型别名)。

我可以将抽象类Foo 重写为特征,我可能会这样做。但我不确定它是否有帮助。

【问题讨论】:

    标签: scala types type-inference inference


    【解决方案1】:

    当类型参数不方便时,应该尝试抽象类型:

    scala> class Bar[I, T](i: I, t: T)
    defined class Bar
    
    scala> class SomeClass[A](a: A)
    defined class SomeClass
    
    scala> trait Trait { type I; type T; type A = Bar[I,T] }
    defined trait Trait
    
    scala> class Foo(x: SomeClass[Foo#A]) extends Trait { type I = String; type T = String }
    defined class Foo
    
    scala> new Foo(new SomeClass(new Bar("", ""))) // works
    res0: Foo = Foo@7e1f613c
    
    scala> new Foo(new SomeClass(new Bar("", 0))) // does not work
    <console>:12: error: type mismatch;
     found   : Int(0)
     required: String
                  new Foo(new SomeClass(new Bar("", 0)))
                                                    ^
    

    【讨论】:

    • 我不确定它是否满足我的需求。当然,我可以从 IT 类型构造类型 A = Bar[I, T]。但我想要一个相反的过程——从给定类型A &lt;: Bar[_, _] 重构类型IT。我想这样做的主要原因是用户可能有Bar[_, _] 的typedef,所以这种方式会减少样板。
    猜你喜欢
    • 2023-04-02
    • 2022-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多