特征/类类型参数优先于方法类型参数的规则是什么

2024-06-26

我已经使用 scala 一段时间了,我认为我真的开始理解一切(好吧,大多数事情......),但我发现自己对 Map 类中的许多方法定义感到困惑。我知道 FoldLeft 等如何工作,但我感到困惑的是 Map 函数中使用的类型参数。我们以 FoldLeft 为例:

foldLeft [B] (z: B)(op: (B, (A, B)) ⇒ B) : B

Map 特征本身的定义采用两个类型参数“A”和“B”(例如 Map[A,+B])。据我所知,当您使用与类/特征的类型参数之一相同的名称为方法定义类型参数时,它会覆盖类/特征值。以 Foo 的定义为例:

class Foo[A : Manifest, B : Manifest] {
  def isAString() = manifest[A] == manifest[String]
  def isAInt() = manifest[A] == manifest[Int]
  def isBString() = manifest[B] == manifest[String]
  def isBInt() = manifest[B] == manifest[Int]
  def nowIsBString[B : Manifest] = manifest[B] == manifest[String]
}

scala> val f = new Foo[String,Int]
f: Foo[String,Int] = Foo@7bacb41

scala> f.isAString
res290: Boolean = true

scala> f.isAInt
res291: Boolean = false

scala> f.isBString
res292: Boolean = false

scala> f.isBInt
res293: Boolean = true

scala> f.nowIsBString[String]
res294: Boolean = true

scala> f.nowIsBString[Int]
res295: Boolean = false

因此,在 FoldLeft 定义中,“B”来自方法定义,“A”来自特征定义。例如:

val xm = Map("test" -> 1, "test2" -> 2)

scala> val foldFn = (z: Int, kv: (String, Int)) => z + kv._2 
foldFn: (Int, (String, Int)) => Int = <function2>

scala> m.foldLeft(0)(foldFn)
res298: Int = 3

这正如预期的那样,函数的“B”与特征的“B”匹配,但是如果我将函数的“B”类型更改为 String 而不是 Int 会怎么样:

scala> val foldFn = (z: String, kv: (String, String)) => z + kv._2 
foldFn: (String, (String, String)) => java.lang.String = <function2>

scala> m.foldLeft("")(foldFn)
<console>:19: error: type mismatch;
 found   : (String, (String, String)) => java.lang.String
 required: (java.lang.String, (java.lang.String, Int)) => java.lang.String
              m.foldLeft("")(foldFn)

因此,我们将 kv 参数更改为 (String, Int):

scala> val foldFn = (z: String, kv: (String, Int)) => z + kv._2 
foldFn: (String, (String, Int)) => java.lang.String = <function2>

scala> m.foldLeft("")(foldFn)
res299: java.lang.String = 12

与我的 Foo 示例不同,在这种情况下,Map 的“B”值优先于函数定义,但仅限于 kv 参数。我期望看到的 FoldLeft 定义如下:

foldLeft[C] (z: C)(op: (C, (A, B)) => C): C

这对我来说会更清楚,但它不是这样定义的。那么有谁知道方法参数何时覆盖特征/类参数以及何时不会覆盖的规则?


Scala 在这方面与 Java 相同,以下内容来自《名称》的“名称”章节Java规范 http://docs.oracle.com/javase/specs/jls/se5.0/html/names.html适用:

一份声明d属于一个名为n隐藏任何声明 其他类型命名n在该点的范围内d发生 整个范围内d.

因此,方法的类型参数将始终隐藏具有相同名称的类或特征类型参数。你的Foo例子证明了这一事实。

您在以下情况中看到的明显反例Map's foldLeft只是令人不快的人工制品 https://issues.scala-lang.org/browse/SI-3834当前版本的 Scaladoc,原样指出 https://stackoverflow.com/a/8398311/334519在您链接的问题的答案中。foldLeft没有定义在Map特质,但在TraversableOnce http://www.scala-lang.org/api/current/scala/collection/TraversableOnce.html,其中没有名为的特征类型参数B at all.

一般来说,在方法中隐藏特征或类的类型参数当然是一个非常糟糕的主意。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

特征/类类型参数优先于方法类型参数的规则是什么 的相关文章

随机推荐

  • 调用 close() 后大文件没有立即刷新到磁盘?

    我正在使用 python 脚本创建大文件 超过1GB 实际上有 8 个 在创建它们之后 我必须创建将使用这些文件的进程 该脚本如下所示 This is more complex function but it basically does
  • Android 上有某种 ASLR 保护吗?

    我想知道是否有人可以访问具有从程序的一个实例到另一个实例的函数地址相同的库 在同一设备上运行时 地址空间布局将非常一致 许多主要系统库都是由 zygote 预加载的 因此由它分叉出来的子级继承为共享映射 以区分为应用程序 我认为在虚拟内存级
  • 没有实例的 Django Formset

    In this http docs djangoproject com en dev topics forms modelforms inline formsetsDjango Doc 解释了如何创建一个表单集 该表单集允许您编辑属于特定作
  • JAX-RS:不区分大小写的路径

    我已将 REST 服务 方法锚定到 URI 模板 Path注解 它看起来像往常一样 GET Path message Produces application json public Response getMessage 但我的 REST
  • 如何从sqlalchemy中的select语句创建新表?

    我正在使用 sqlalchemy 的核心功能来编写一些抽象层 该层本身需要能够从 select 语句创建表 示例代码 metadata MetaData bind engine table Table table name metadata
  • 开发和生产 SQL Server 之间使用不同的排序规则会出现哪些问题?

    盘问 无法更新 sys columns 还有其他方法吗 https stackoverflow com questions 4018347 unable to update sys columns any other approach含糊地
  • >> 在 PHP 中是什么意思?

    考虑 echo 50 gt gt 4 Output 3 为什么输出3呢 50 的二进制是11 0010 右移 4 次11等于 3 See PHP 文档 http php net manual en language operators bi
  • 如何将参数传递给 JHipster 中的自定义错误消息?

    我仍在学习 JHipster 所以今天我想自己进行一些验证练习 并尝试向我的前端发送有意义的错误消息 这是我尝试过的 在我的控制器中 我有以下内容 POST lessons Create a new lesson of 45 min if
  • 如何在 firebug 中导致调试中断

    我试图在检测到错误时让萤火虫中断 具体来说 我在代码中进行了一些内部检查 例如断言 我希望 Firebug 在失败时停止 我尝试了几种不同的方法 并想知道其他人是怎么做的 以下是我尝试过的方法 输入一些无效代码 以便如果出现错误 函数断言
  • AFNetworking 的 UICollectionView 异步下载错误

    您好 我正在使用目录列表创建 Uicollection 视图 点击单元格时必须下载 PDF 它在一个视图中完美运行 但在另一个视图中出现错误 thread 1 tid 0x4b2ce 0x000000018d14f9b8 CoreFound
  • 为什么 NodeJS 不支持 String.prototype.replaceAll?

    这个字符串方法存在于 browserland 中 但不存在于 Node 中 为什么不 它既不是全新的 也不是异国情调的 replaceAll is part of ECMA 262 src https tc39 es ecma262 sec
  • 如何在响应式设计中禁用缩放功能?

    在使用 iPad iPhone 和 或其他智能手机时 如何禁用响应式设计页面中的放大和缩小功能 有什么办法可以控制吗 创建 META 视口标签 并设置用户可扩展属性为 否 如下所示 更新的答案
  • 运行 Fiddler 作为 HTTPS 服务器的反向代理

    我有以下情况 2台主机 一台是客户端 另一台是HTTPS服务器 Client
  • 确定文件是否打开

    有什么方法可以确定文件是否被任何包括不锁定文件的应用程序 如记事本 打开 我需要检测给定文件 myfile txt 何时不再在包括记事本在内的任何应用程序中打开 因此我无法使用具有独占访问权限的 File Open 进行测试 因为该文件没有
  • OpenAPI 查询参数描述未设置为文本框作为占位符

    我已经使用描述来添加查询参数的详细信息 例如 parameters name role in query required true schema type string description This is test descripti
  • PHP 和 ESB(使用 Mule)(ESB:企业服务总线)

    您在 PHP 项目中何时 何地以及为何使用 ESB 您认为在何处 何时以及为何在 PHP 项目中使用 ESB 有意义 ESB 以及像 Mule 这样的 ESB 促进者 是否提供了 PHP 和本地 LAMP 技术所缺乏的任何功能 Edit 我
  • Android AsyncTask 启动另一个 AsyncTask

    我目前正在 AsyncTask 的 onPostExecute 方法中执行类似的操作 其中NewTask is not当前正在执行的任务 private class OlderTask extends AsyncTask
  • 如何在 PHP 中识别请求的页面

    有没有简单的方法来识别最初处理请求的文件 忽略获取参数并处理 至少是基本的 映射 例如 to index php 理想情况下 我正在寻找类似的东西 SERVER REQUEST URI 但无论 get 参数如何 它都会返回相同的值 并且该值
  • 如何使用 selenium 和 junit 测试多个浏览器(版本)

    我刚刚发现了硒 一个很棒的工具 我计划运行 使用 selenium ide 生成的 junit4 代码 但我需要它与许多浏览器 网络驱动程序一起运行 这个用例有 junit java 模式吗 我的第一个想法是使用 RunWith Param
  • 特征/类类型参数优先于方法类型参数的规则是什么

    我已经使用 scala 一段时间了 我认为我真的开始理解一切 好吧 大多数事情 但我发现自己对 Map 类中的许多方法定义感到困惑 我知道 FoldLeft 等如何工作 但我感到困惑的是 Map 函数中使用的类型参数 我们以 FoldLef