【问题标题】:Inheriting from generic classes in scala从scala中的泛型类继承
【发布时间】:2014-10-15 20:52:58
【问题描述】:

谁能解释一下为什么下面的示例代码不能编译

class Animal(val mass : Int)
class Person(val personMass :Int,val name:String) extends Animal(personMass)

class SocialGroup[T <: Animal]

class AlturisticSocialGroup[T <: Animal ] extends SocialGroup[T]

class Society[A <: SocialGroup[B]]

这里的想法是我想要一个由 SocialGroup 的子类参数化的社会。我希望能够做到

val animalSociety : Society[SocialGroup[Animal]] = ......

val niceSociety = Society[AltruisticSocialGroup[Person]] = ....

编译器给我的

错误:未找到:类型 B

我确定我遗漏了一些明显的东西,但我们将不胜感激任何帮助

【问题讨论】:

    标签: scala generics inheritance


    【解决方案1】:

    你需要这个吗?

    class Society[A <: SocialGroup[B], B <: Animal]
    

    这样你就可以使用

    val animalSociety: Society[SocialGroup[Animal], Animal] = ...
    val niceSociety: Society[AltruisticSocialGroup[Person], Person] = ...
    

    你需要类型参数A B,所以基本上你需要像class ClassName[A, B]这样具有适当属性的东西。

    编辑:
    正如@Kigyo所说,如果你不需要对B进行额外限制,你可以使用匿名类型参数_

    class Society[A <: SocialGroup[_]]
    

    这会将B替换为通配符_,而_ &lt;: Animal由于定义SocialGroup[T &lt;: Animal],而_不需要声明,因为它没有名称,因此代码会更短.

    val animalSociety: Society[SocialGroup[Animal]] = ...
    val niceSociety: Society[AltruisticSocialGroup[Person]] = ...
    

    更多解释可以看https://twitter.github.io/scala_school/type-basics.html

    有时你并不关心能够命名一个类型变量,因为 示例:

    scala&gt; def count[A](l: List[A]) = l.size count: [A](List[A])Int

    相反,您可以使用“通配符”:

    scala&gt; def count(l: List[_]) = l.size count: (List[_])Int

    【讨论】:

    • A &lt;: SocialGroup[_] 也应该这样做,因为SocialGroup 中已经存在约束T &lt;: Animal
    • @Kigyo 好的。我也会添加这个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2020-09-11
    • 2019-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多