首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala - Typeclass重写抽象方法

Scala - Typeclass重写抽象方法
EN

Stack Overflow用户
提问于 2021-12-16 12:05:26
回答 2查看 94关注 0票数 0

我正在与Scala2.12做一些斗争:

我有以下等级:

代码语言:javascript
复制
trait A

case class B(format: String) extends A

trait Writer {
  def write(config: A): Unit
}


val writer = new Writer {
  override def write(config: A) = println("hi")
}

val w = B("console")
writer.write(w)

效果很好。但我想为作者提供一个替代实现:

代码语言:javascript
复制
val writer = new Writer {
  override def write(config: B) = println("hi")
}

但我得到了object creation impossible, since method write in trait Writer of type (config: Playground.A)Unit is not defined

我以为B是A,这应该管用。如何使用B类型的配置覆盖B <: A

Scastie:https://scastie.scala-lang.org/QBaiiDP4Sj2lptUjrWLJYw

------------------------------------------------------------编辑:

根据一些输入,我将实现更改为:

代码语言:javascript
复制
sealed trait A

case class B(format: String) extends A

trait Writer[+T] {
  def write[S >: T](config: S): Unit
}


val writer: Writer[A] = new Writer[B] {
  override def write[B](config: B) = println("hi")
}


val b = B("console")
writer.write(b)

这很管用。

但是,如果我修改它以访问config中的变量,它就会中断:

代码语言:javascript
复制
sealed trait A

case class B(format: String) extends A

trait Writer[+T] {
  def write[S >: T](config: S): Unit
}


val writer: Writer[A] = new Writer[B] {
  override def write[B](config: B) = println(config.format)
}


val b = B("console")
writer.write(b)

value format is not a member of type parameter B

https://scastie.scala-lang.org/Xj2rKbbiTmG7raZgQZYfHA

感谢你的投入。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-12-18 00:29:55

你和你的最新版本很接近。正如Matthias所指出的,write方法声明了一个新的类型参数,但是应该使用在该特性上声明的参数。此外,类型参数应该是相反的。

此代码编译并打印console

代码语言:javascript
复制
sealed trait A

case class B(format: String) extends A

trait Writer[-T <: A] {
  def write(config: T): Unit
}


val writer: Writer[B] = new Writer[B] {
  override def write(config: B) = println(config.format)
}


val b = B("console")
writer.write(b)

注意,因为BA的一个子类型,所以您也可以在B实例中使用Writer[A]。因为Writer是反变体,所以可以将Writer[A]类型的值赋值给Writer[B]类型的变量。

代码语言:javascript
复制
val aWriter: Writer[B] = new Writer[A]  {
  override def write(config: A) = println(s"Got A: $config")
}

aWriter.write(b) // prints "Got A: B(console)"

您不能做相反的事情(将Writer[B]值赋给Writer[A]变量),因为Writer[A]可以接受A类型的任何值,而Writer[B]只能接受B类型的值。

https://scastie.scala-lang.org/TimMoore/bd5E1p99TLCDVfMbElKqFg/8

票数 1
EN

Stack Overflow用户

发布于 2021-12-16 12:35:07

它不能工作,因为Writer声明它的write方法将接受任意的A。如果有人决定将一个不是BB传递给writer.write,该怎么办?然后它就不能工作了,所以编译器会阻止您这样做。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70378739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档