Scala 函数变体和重写

2024-04-16

我在理解重载时方法的差异时遇到了一些问题。

虽然由于返回类型的协方差,这可以完美地工作

class Bla 
class Fasel extends Bla 

trait Test[A] {
 def tester(): Bla = new Bla
}

class FooTest[A](a: A) extends Test[A] {
 override def tester(): Fasel = new Fasel                                      
}

即使函数在它们的方面是逆变的,这个也会失败 参数类型。

class Bla 
class Fasel extends Bla 

trait Test[A] {
 def tester(a: Fasel): Bla = new Bla                                           
}

class FooTest[A](a: A) extends Test[A] {
 override def tester(a: Bla): Fasel = new Fasel
}

我在这里犯了什么错?有什么指点吗?

问候, 雷鸟


这里发生了两件事:

  1. 一个函数和一个方法不是同一件事 https://stackoverflow.com/questions/2529184/difference-between-method-and-function-in-scala
  2. 方法的参数类型不是多态的

Your tester方法是方法,not a Function1。可以使用下划线语法将其提升为函数:

val f = (new FooTest[String]).tester _ // Fasel => Bla

该函数的输入类型将是逆变的。 (不过,值得一提的是,该功能无法参数化还值得一提的是我必须有一个实例Foo or FooTest为了获得一个函数对象tester方法。这当然是根据第一次观察得出的!)

函数是一个对象,它不能被覆盖因为那没有意义。方法可以被重写。然而,正如我上面所说,重写在方法的参数类型中不是多态的。例如:

class A {
  def foo(a : Any) = println("A: " + a)
}

class B extends A {
  override def foo(s : String) = println("B " + s) //will not compile!
}

上面示例中的两个方法是两个独立的方法:动态调度仅适用于方法目标(即调用它的对象)。

在上面的示例中,如果删除override声明,代码将编译。如果您运行以下命令:

(new B).foo(1)   //prints A 1
(new B).foo("s") //prints B s

这是因为,虽然这两种方法都被称为foo,它们是完全不同的方法(即我有超载 foo, not 被覆盖它)。最好将其理解为方法的参数(包括它们的类型)构成该方法的唯一参数的一部分name。仅当一种方法完全相同时才会覆盖另一种方法name.


本质上你混淆了两个是什么分离且不相关的为了清楚起见,我将把你的问题中的内容写下来:

  • 方差注释Function1定义一个函数作为另一个函数的子类型意味着什么(因此可分配的到给定类型的引用)。
  • 可以在子类上重写方法,并且语言规范概述了何时发生此类重写的规则。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala 函数变体和重写 的相关文章

  • 解析嵌套括号内包含的值

    我只是在开玩笑 奇怪地发现在简单的递归函数中解析嵌套括号有点棘手 例如 如果程序的目的是查找用户详细信息 它可能来自 name surname age to Bob Builder age 然后到Bob Builder 20 这是一个用于在
  • 如何使用 scala 宏打印变量名称和值?

    我确信有一种更优雅的方式来编写以下宏来打印变量的名称和值 def mprintx c Context linecode c Expr Any c Expr Unit import c universe val namez c enclosi
  • 如何询问 Scala 类型参数的所有实例化是否存在证据?

    给定皮亚诺数的以下类型级加法函数 sealed trait Nat class O extends Nat class S N lt Nat extends Nat type plus a lt Nat b lt Nat a match c
  • scala 中 'Array[Int]' 隐式转换为 'Int => Int' 的地方在哪里?

    这是一个问题this https stackoverflow com questions 70000384 why val arr int int array1 2 3 is allowed in scala 现在我们已经证明了Array
  • Scala repl 抛出错误

    当我打字时scala在终端上启动 repl 它会抛出此错误 scala gt init error error while loading AnnotatedElement class file usr lib jvm java 8 ora
  • 映射存在类型列表

    我有一个要映射的存在类型对象的列表 像这样的东西 sealed abstract class IntBox val v Int case object IB1 extends IntBox 1 case object IB2 extends
  • Joda Time 类没有任何构造函数...为什么?我做错了什么?

    显然 Eclipse 上的 Scala 试图让我相信DateTime Period DateMidnightJoda Time 中的许多其他类没有任何构造函数 考虑到它们的文档显示了构造函数和许多方法 这很奇怪 我唯一可以访问的是静态方法
  • “函数是第一等值”这到底是什么意思?

    有人可以用一些很好的例子清楚地解释它吗 在解释函数式编程时 我在 Scala 中遇到了这句话 一流 并不是一个正式定义的概念 但它通常意味着一个实体具有三个属性 有可能used 不受限制 只要 普通 值可以 即从函数传递和返回 放入容器等
  • 覆盖 Predef 的隐式转换

    我有多个返回 java lang Integer 的方法 然后使用 Scala 的 Predef 隐式转换将其隐式转换为 Int 下面是它的编写方式there https github com scala scala blob v2 11
  • Python子类方法从超类方法继承装饰器

    我有一个具有retrieve 方法的超类 并且它的子类每个都实现自己的retrieve 方法 我希望每个retrieve 方法都被装饰为在收到相同参数时缓存返回值 而不必在每个子类中装饰该方法 装饰器似乎不能被继承 我可能可以调用超类的方法
  • ';'预期但发现“导入” - Scala 和 Spark

    我正在尝试使用 Spark 和 Scala 来编译一个独立的应用程序 我不知道为什么会收到此错误 topicModel scala 2 expected but import found error import org apache sp
  • 未调用 C++ 重写函数

    我遇到了一个问题 即未调用重载函数 而是调用了基函数 我怀疑这与项目文件之间的划分方式有关 在文件 obj1 h obj1 cpp 中我有这样的东西 class obj1 public void print void obj1 print
  • Scala 中抛出异常,什么是“官方规则”

    我正在 Coursera 上学习 Scala 课程 我也开始阅读 Odersky 的 Scala 书 我经常听到的是 在函数式语言中抛出异常不是一个好主意 因为它破坏了控制流 并且我们通常返回一个失败或成功的 Either Scala 2
  • IntelliJ IDEA 13:新的 Scala SBT 项目尚未生成 src 目录结构

    我按照 Jetbrains 网站上的入门视频设置 IntelliJ IDEA 13 1 Community Edition 以与 Scala 配合使用 Scala 插件 v0 36 431 已安装 当我使用向导创建一个新的 Scala SB
  • 在打字稿中通过 this 从派生类型调用构造函数

    在我的打字稿中 我尝试通过基类中的方法创建 克隆子对象 这是我的 简化的 设置 abstract class BaseClass
  • 如何在 Apache Spark 中通过 DStream 使用特征提取

    我有通过 DStream 从 Kafka 到达的数据 我想进行特征提取以获得一些关键词 我不想等待所有数据的到达 因为它是可能永远不会结束的连续流 所以我希望以块的形式执行提取 如果准确性会受到一点影响 对我来说并不重要 到目前为止 我整理
  • 继承的静态成员的静态初始化

    考虑这个示例代码 public class A
  • Akka Stream Graph 恢复问题

    我创建了一个图表来并行化具有相同输入的两个流 这些流产生 Future Option Entity 如果 flowA 失败 我想返回 Future None 但恢复似乎没有被调用 val graph Flow Input Future Op
  • Scala 的代码覆盖率工具 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 模拟 BlazeClientBuilder[IO] 以返回模拟客户端[IO]

    我正在使用BlazeClientBuilder IO resource方法得到Client IO 现在 我想模拟客户端进行单元测试 但不知道该怎么做 有没有一个好的方法来嘲笑这个 我会怎么做 class ExternalCall val r

随机推荐