我有以下函数,它做递归:
@tailrec private def pool[F[_]: Monad, A] : Consumer[String, String] => (Vector[KkConsumerRecord] => F[A]) => IO[Unit] = consumer => cb => { val records: ConsumerRecords[String, String] = consumer.poll(Long.MaxValue) val converted = records.iterator().asScala.map(rec => { KkConsumerRecord(rec.key(), rec.value(), rec.offset(), rec.partition(), rec.topic()) }) val vec = converted.foldLeft(Vector.empty[KkConsumerRecord]) { (b, a) => a +: b } cb(vec) pool(consumer)(cb) }
编译器抱怨:
[error] /home/developer/Desktop/microservices/bary/kafka-api/src/main/scala/io/khinkali/Consumer/KkConsumer.scala:57:10: type mismatch; [error] found : org.apache.kafka.clients.consumer.Consumer[String,String] [error] required: cats.Monad[?] [error] pool(consumer)(cb) [error] ^ [error] two errors found
我究竟做错了什么?
以下代码编译:
import cats.Monad import cats.effect.IO import org.apache.kafka.clients.consumer.{Consumer, ConsumerRecords} import scala.collection.JavaConverters._ import scala.annotation.tailrec object App { case class KkConsumerRecord(key: String, value: String, offset: Long, partition: Int, topic: String) // @tailrec private def pool[F[_]: Monad, A] : Consumer[String, String] => (Vector[KkConsumerRecord] => F[A]) => IO[Unit] = consumer => cb => { val records: ConsumerRecords[String, String] = consumer.poll(Long.MaxValue) val converted = records.iterator().asScala.map(rec => { KkConsumerRecord(rec.key(), rec.value(), rec.offset(), rec.partition(), rec.topic()) }) val vec = converted.foldLeft(Vector.empty[KkConsumerRecord]) { (b, a) => a +: b } cb(vec) pool.apply(consumer)(cb) } }
def pool[F[_]: Monad, A]
意味着def pool[F[_], A](implicit monad: Monad[F])
编译器被误consumer
认为是隐式参数.
tailrec
注释被删除,因为pool
不是尾递归(最后一个操作是构造lambda,我猜它叫做尾递归模数).
如果你想使它尾递归,你可以将其重写为
@tailrec private def pool[F[_]: Monad, A](consumer: Consumer[String, String])(cb: Vector[KkConsumerRecord] => F[A]): IO[Unit] = { val records: ConsumerRecords[String, String] = consumer.poll(Long.MaxValue) val converted = records.iterator().asScala.map(rec => { KkConsumerRecord(rec.key(), rec.value(), rec.offset(), rec.partition(), rec.topic()) }) val vec = converted.foldLeft(Vector.empty[KkConsumerRecord]) { (b, a) => a +: b } cb(vec) pool(consumer)(cb) }