Несоответствие типов при неявном преобразовании классов - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть следующий фрагмент кода

  trait HTMLWritable {
    def toHTML: String
  }

  case class User(name: String, age: Int, email: String) extends HTMLWritable {
    override def toHTML: String = s"<div> $name ($age) <a href=$email/> </div>"
  }

  trait HTMLSerializer[T] {
    def serialize(value: T): String
  }

  implicit object UserSerializer extends HTMLSerializer[User] {
    override def serialize(user: User): String = s"<div> ${user.name} (${user.age}) <a href=${user.email}/> </div>"

  }

  implicit class HTMLEnrichment[T](value: T) {
    def toHTML(serializer: HTMLSerializer[T]): String = serializer.serialize(value)
  }

  val john = User("John", 32, "john@domain.com")

  println(john.toHTML(UserSerializer))

, который выдает следующую ошибку

Error:(30, 23) type mismatch;
 found   : advanced.StackOverflowQuestion.UserSerializer.type
 required: Int
  println(john.toHTML(UserSerializer))

ошибка исчезнет, ​​если я переименую HTMLWritable 'toHTML метод в toHtml или вообще к чему-то другому и сохранению оператора print таким, как это

 trait HTMLWritable {
    def tohtml: String
  }

  case class User(name: String, age: Int, email: String) extends HTMLWritable {
    override def tohtml: String = s"<div> $name ($age) <a href=$email/> </div>"
  }

и вопрос: почему здесь смущен компилятор?

Я бы ожидал, что метод класса будет предпочтительным и будет подчиняться неявному, только если метод не найден, но это несоответствие типов является совершенно другим зверем.

1 Ответ

2 голосов
/ 15 апреля 2020

Компилятор считает, что .toHTML в john.toHTML(UserSerializer) является методом HTMLWritable#toHTML вместо метода расширения HTMLEnrichment#toHTML.

Тогда согласно HTMLWritable#toHTML подписи, john.toHTML является String и john.toHTML(UserSerializer) - это john.toHTML.apply(UserSerializer), то есть String#apply, ожидающее Int.

...