Scala 如何协助多态性中的类型推断?

Scala 如何协助多态性中的类型推断?,scala,Scala,旧标题:如何显示或断言列表可遍历一次? 我一直在努力为一些班级设计一个特点。在trait中,我尝试了以下两种方法之一: //First try: def addData[A <: Any](newTweets: => List[A]): Unit //Second try def addData[A <: List[Any]](newTweets: => A): Unit //Third try def addData[A <: List[A

旧标题:如何显示或断言列表可遍历一次?

我一直在努力为一些班级设计一个特点。在trait中,我尝试了以下两种方法之一:

  //First try:
  def addData[A <: Any](newTweets: => List[A]): Unit
  //Second try
  def addData[A <: List[Any]](newTweets: => A): Unit
  //Third try
  def addData[A <: List[Any]](newTweets: => A): Unit

我最困惑的是,我认为这个列表应该实现一次。此外,在使类从自定义特性扩展之前,这种方法工作得很好。唯一的区别是我没有在类中参数化方法的类型,例如,我有
def addData(…
而不是
addData[Tweet](…
)。但是如果我离开,在从trait扩展时我没有更改要参数化的函数形式,我会收到一个投诉,说我没有实现
addData

我欢迎新的方法和提示来解释为什么会发生这个错误(因为这个列表应该被遍历一次)

编辑

在忘记列表并将所有内容都设置为可横向更改一次后,我仍然会遇到一个可能相同的错误,但可能更具启发性(只是对我来说不是):

我还将包括更完整的代码:

特质

package edu.cornell.comm.api

import scala.collection.{TraversableOnce}
import scala.collection.mutable.{MutableList, Publisher}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import edu.cornell.comm.twitter.types.Tweet
import scala.collection.mutable.{Publisher}

trait MicroBlogPublisher[T] extends Publisher[Future[String]] {

  def addData[T](newTweets: => TraversableOnce[T]): Unit

}
实施一

package edu.cornell.comm.twitter

import edu.cornell.comm.api.MicroBlogPublisher
import edu.cornell.comm.twitter.types.IOHelpers._
import edu.cornell.comm.twitter.types._
import play.api.libs.json.{JsValue, Json}
import scala.collection.mutable.{MutableList, Publisher}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._

class JsonPublisher extends MicroBlogPublisher[Future[JsValue]] {

  protected var dataList: MutableList[Future[JsValue]] = MutableList.empty

  def addData[Future[JsValue]](newData: => TraversableOnce[Future[JsValue]]): Unit = {
    dataList ++= newData
  }


}
实施二

package edu.cornell.comm.twitter

import edu.cornell.comm.api.MicroBlogPublisher
import play.api.libs.json.Json
import scala.collection.{TraversableOnce}
import scala.collection.mutable.{MutableList, Publisher}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import edu.cornell.comm.twitter.types._
import IOHelpers._

class TweetPublisher extends MicroBlogPublisher[Tweet] {


  protected var tweetsList: MutableList[Tweet] = MutableList.empty


  def addData[Tweet](newTweets: => TraversableOnce[Tweet]): Unit = {
    tweetsList ++= newTweets
    tweetsList = tweetsList.sortWith(
      (a,b) => a.created_at.getTime < b.created_at.getTime
    )
  }


}
包edu.cornell.comm.twitter
导入edu.cornell.comm.api.MicroBlogPublisher
导入play.api.libs.json.json
导入scala.collection.{TraversableOnce}
导入scala.collection.mutable.{MutableList,Publisher}
导入scala.concurrent.ExecutionContext.Implicits.global
导入scala.concurrent_
导入edu.cornell.comm.twitter.types_
导入IOHelpers_
类TweetPublisher扩展了MicroBlogPublisher[Tweet]{
受保护的var tweetsList:MutableList[Tweet]=MutableList.empty
def addData[Tweet](newTweets:=>TraversableOnce[Tweet]):单位={
tweetsList++=newweets
tweetsList=tweetsList.sortWith(
(a,b)=>a.created_at.getTime
你的案子真有趣

以下是正确的代码:

trait MicroBlogPublisher[T] extends Publisher[Future[String]] {
  def addData(newTweets: => TraversableOnce[T]): Unit
}

class JsonPublisher extends MicroBlogPublisher[Future[JsValue]] {
  protected var dataList: MutableList[Future[JsValue]] = MutableList.empty
  override def addData(newData: => TraversableOnce[Future[JsValue]]): Unit = {
    dataList ++= newData
  }
}
问题是方法
addData
声明了自己的泛型类型
T
,这与trait的类型参数
T
完全无关。现在有趣的是,在具体实现中,例如
JsonPublisher
,声明
def addData[Future[JsValue]](…
实际上声明了两个泛型类型参数,它们的名称很混乱
Future
JsValue
。但实际上,此声明是
def addData[P[Q]]的同义词(…

现在你该如何避免这个错误


对于我来说,Idea在
MicroBlogPublisher
中显示了声明
def addData[T]
的警告,说:“类型参数T的可疑阴影”。它应该告诉你,
T
现在看起来是什么样子。接下来,当你重写方法时,不要忘记
override
关键字。当重写方法的签名出现问题时,你会得到通知。

我想这可能与Scala的“秩1多态性”有关,尽管我还不能马上确定解决这个问题的方法:你能详细说明你的代码吗:
dataList
是如何定义的,在哪里定义的,你的两个特征是如何相互扩展的(包括类型参数),重写
dataList
addData
方法。我没有在trait中包含dataList;我现在已更新(并更改了标题),请在编辑后查看。也许我应该稍后再更改标题…我可以理解为什么你现在说这很有趣…这绝对是一个特殊的初学者错误。有趣的是,我当时并没有意识到这一警告,尽管当我查看时,我的代码可能处于稍微不同的状态。我有
类型不匹配,预期:TraversableOnce[Tweet],实际:TraversableOnce[Tweet]
…一个有趣的错误,因为其他原因我不止一次遇到过。
package edu.cornell.comm.api

import scala.collection.{TraversableOnce}
import scala.collection.mutable.{MutableList, Publisher}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import edu.cornell.comm.twitter.types.Tweet
import scala.collection.mutable.{Publisher}

trait MicroBlogPublisher[T] extends Publisher[Future[String]] {

  def addData[T](newTweets: => TraversableOnce[T]): Unit

}
package edu.cornell.comm.twitter

import edu.cornell.comm.api.MicroBlogPublisher
import edu.cornell.comm.twitter.types.IOHelpers._
import edu.cornell.comm.twitter.types._
import play.api.libs.json.{JsValue, Json}
import scala.collection.mutable.{MutableList, Publisher}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._

class JsonPublisher extends MicroBlogPublisher[Future[JsValue]] {

  protected var dataList: MutableList[Future[JsValue]] = MutableList.empty

  def addData[Future[JsValue]](newData: => TraversableOnce[Future[JsValue]]): Unit = {
    dataList ++= newData
  }


}
package edu.cornell.comm.twitter

import edu.cornell.comm.api.MicroBlogPublisher
import play.api.libs.json.Json
import scala.collection.{TraversableOnce}
import scala.collection.mutable.{MutableList, Publisher}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import edu.cornell.comm.twitter.types._
import IOHelpers._

class TweetPublisher extends MicroBlogPublisher[Tweet] {


  protected var tweetsList: MutableList[Tweet] = MutableList.empty


  def addData[Tweet](newTweets: => TraversableOnce[Tweet]): Unit = {
    tweetsList ++= newTweets
    tweetsList = tweetsList.sortWith(
      (a,b) => a.created_at.getTime < b.created_at.getTime
    )
  }


}
trait MicroBlogPublisher[T] extends Publisher[Future[String]] {
  def addData(newTweets: => TraversableOnce[T]): Unit
}

class JsonPublisher extends MicroBlogPublisher[Future[JsValue]] {
  protected var dataList: MutableList[Future[JsValue]] = MutableList.empty
  override def addData(newData: => TraversableOnce[Future[JsValue]]): Unit = {
    dataList ++= newData
  }
}