为什么scalac推断`Foo with Bar`而不只是'Foo`匹配/ case返回类型?

时间:2014-12-02 10:49:55

标签: scala traits

在模型类中,我有一个简单的getter函数,如下所示:

  def geoLoc = {
    geoQuant match {
      case "COUNTRY" => Country.find.byId(geoLocId)
      case "PROVICE" => Province.find.byId(geoLocId.toLong)
      case "CITY" => City.find.byId(geoLocId.toLong)
      case "STREET" => Street.find.byId(geoLocId.toLong)
    }
  }

想法是获取对象的GeoLocation - 可以是四种类型中的任何一种。从我看到的,函数geoLoc有一个返回类型,它是所有的超类:CountryProvinceCity& Street - 扩展Model类。

相反,函数的返回类型为Model with GeoEntity,其中GeoEntity是每个类与Model一起的特征。

为什么会这样?如何使函数返回具有模式匹配的特定类型?

1 个答案:

答案 0 :(得分:2)

Scala推断出最具体的类型。四个实例中的每一个都是ModelGeoEntity,因此这是推断类型:Model with GeoEntity。如果您希望函数返回不太具体的Model类型(所有Model with GeoEntity都是Model s,但并非所有Models都是Model with GeoEntity s),只需使用该类型注释函数:def geoLoc: Model = ...

该函数只能有一种返回类型,并且无法在编译时知道它将遇到的四种情况中的哪一种。如果你想为每种情况返回一个更具体的类型,那么关于这个对象需要哪种类型的信息需要成为对象类型的一部分(或者你可以使用依赖类型,但类型信息仍然必须来自某个地方) 。例如。你可以使你的对象成为一个抽象的泛型类型,具有特定实例的子类:

class MyObject[LocationType <: Model] {
  def geoLoc: LocationType
}
class MyObjectCountry extends MyObject[Country] {
  def geoLoc: Country = ...
}
class MyObjectProvice extends MyObject[Province] {
  def geoLoc: Province = ...
}