繁体   English   中英

Scala为什么要编译此代码?

[英]Scala Why does this code compile?

这取自Coursera在Scala课程中进行的函数编程的第6周。

我试图将我的头缠在下面的代码片段中。 尽管charcode的参数列表中没有(c: Char) ,如何将charCode传递给字符串的map方法?

/* define the map of numbers to letters */
val nmem = Map( '2' -> "ABC", '3' -> "DEF", '4' -> "GHI", '5' -> "JKL", '6' 
-> "MNO", '7' -> "PQRS", '8' -> "TUV", '9' -> "WXYZ")

 /* invert the map the get a map of letters to digits */
val charCode: Map[Char, Char] = for ((digit, str) <- nmem; ltr <- str) yield 
ltr -> digit

/* define a function that returns the numbers of a given word */
def wordCode(word: String): String = word.toUpperCase map charCode

我习惯于传递函数来像这样map

  val s = "JAVA"
  val str = s map (lower)
  def lower(c: Char) = c.toLower

您可以看到lower采用了char作为参数

此外,奥德斯基教授还提到:“类Map [Key,Value]也扩展了Function type Key => value,因此映射可以在所有函数可以使用的地方使用”。 这就是为什么上面的代码行得通吗? 如果是,怎么办? 我似乎找不到任何文档? “地图可以在所有功能可以使用的地方使用”是什么意思?

非常感谢,

你是对的。 之所以有效,是因为Map[A, B] 实现了 Function1[A, B] 字符串的map方法需要一个函数来将每个字符转换为另一个字符。 也就是说, Function1[Char, Char] ,可以写为Char => Char

当您使用Map[Char, Char]调用map时,编译器将实现Function1[Char, Char]从而检查它实际上是Char => Char

如何实施?

您可以将Map[A, B]视为PartialFunction[A, B] 即,为有限数量的输入实现的功能。 Map[A, B]只是从类型A的键到类型B的值的映射。 因此,您的A => B函数实现为:如果map包含类型A的键,则返回其类型B值。 如果不存在,则不会为该A定义部分函数。

层次结构

使之成为可能的层次结构是:

  • Map实现MapLike
  • MapLike实现PartialFunction
  • PartialFunction实现Function1

然后,如果您查看MapLike ,将会发现def isDefinedAt(key: K) = contains(key) 告诉分函数是否定义了给定值。 然后,它还实现Function1所需的def apply(key: K): V

您可以将映射视为部分函数的一种特殊类型-部分意味着不必定义所有值。

也就是说,映射m = Map[S,T]也是S=>T类型的函数。

让我们举个例子

scala> val includes = Map( 1 -> true, 2->false, 3-> false, 4->true)
includes: scala.collection.immutable.Map[Int,Boolean] = Map(1 -> true, 2 -> false, 3 -> false, 4 -> true)

scala> (1 to 4).filter(includes)
res6: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 4)

(如果序列中的值丢失,则会出现运行时错误)。

因此,在您的问题中,您要将Map charCode传递给map函数,您问为什么要编译?

Scala中的String是Java的string的类型别名。 但是在Predef ,存在从StringStringWrapper的隐式转换(低优先级)-将字符串转换为Char序列,而StringOps (较高优先级)将注入收集方法(如map )。 您可以在文档中阅读有关字符串的更多信息

因此,Scala编译器将您的String视为Char的序列,并且map函数使用提供的“函数”(即charCode映射)转换每个成员。

Map[A, B]扩展了PartialFunction[A, B] 即使这是有点的红鲱鱼 ,每PartialFunction[A, B]也是一个函数A => B (它引发错误,如果它不能找到的键)。 map方法期望函数A => B ,因此所有内容都可以很好地组合在一起。

总而言之,

  • charCode是一个Map[Char, Char]
  • 因此它扩展了PartialFunction[Char, Char]
  • 因此它也是一个普通函数Char => Char
  • 它可以作为参数传递给string.map

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM