首页 > 解决方案 > avro4s:找不到参数 schemaFor 的隐式值:com.sksamuel.avro4s.SchemaFor[T]

问题描述

我的要求需要上课,应该使用avro4s返回一个 avro-schema 。下面是代码,我正在尝试:

我们的想法是实现这样的目标


import scala.reflect.ClassTag
import com.sksamuel.avro4s.AvroSchema

case class Ingredient(name: String, sugar: Double, fat: Double)

case class Pizza(
    name: String,
    ingredients: Seq[Ingredient],
    vegetarian: Boolean,
    vegan: Boolean,
    calories: Int
)

class AvroUtil[T: ClassTag](implicit m: Manifest[T]) {

  def caseClassToAvroSchema() = {
    val schema = AvroSchema[T]
    schema
  }

}

new AvroUtil[Pizza].caseClassToAvroSchema()

我怎样才能解决这个问题?

错误 - 找不到参数 schemaFor 的隐式值:com.sksamuel.avro4s.SchemaFor[T]

斯卡拉版本 - 2.12.8

Avro4s-“com.sksamuel.avro4s”%%“avro4s-core”%“3.1.1”

标签: scalaavro4s

解决方案


我看到 AvroUtil 中的上下文绑定“[T: ClassTag]”信息导致了错误。

引用独立对象 'AvroSchema' 的 'apply[T](implicit schemaFor: SchemaFor[T])' 方法(上面通过 'AvroSchema[T]' 调用):如果该方法没有提供参数值并且编译器发现没有范围内的隐式对象,则默认情况下将通过特征 'MagnoliaDerivedSchemaFors' 创建一个隐式 'SchemaFor[T]' 实例

implicit def gen[T]: SchemaFor[T] = macro Magnolia.gen[T]

上下文绑定信息避免构造此默认对象,因此您会收到错误消息。似乎使用现有的“AvroSchema”独立对象应用方法而不是使用新类很好。另一种方法是将'AvroUtil'转换为独立对象(类似于下面的代码,与'AvroSchema'非常相似)并使用apply方法:

import com.sksamuel.avro4s.{AvroSchema, SchemaFor}
import org.apache.avro.Schema    

object AvroUtil {

      def apply[T](implicit schemaFor: SchemaFor[T]): Schema =
        AvroSchema[T](schemaFor)
    }

推荐阅读