我正在Coursera中学习有关Scala函数式编程的课程。我在第六周。
我有以下代码:
/* 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 to get a map of letters to digits */
val charCode: Map[Char, Char] =
for {
(digit, str) <- nmem
ltr <- str
} yield ltr -> digit
我的问题是理解力如何工作? nmem
将键(字符)和值(字符串)引入digit和str。后来我们有了:ltr <-str,我不知道它是如何工作的,因为我不了解程序如何知道ltr是一个字符而不是一个字符串。
谢谢。
答案 0 :(得分:2)
对这种for
的理解被废止了
nmem.flatMap { case (digit, str) => str.map { ltr => (ltr, digit) } }
由于nmem
的类型为Map[Char, String]
,因此编译器知道(digit, str)
的类型必须为(Char, String)
。因此,它知道str
的类型为String
。 String
的元素类型为Char
,因此ltr
的类型被推断为Char
。
如果您想写下类型推断的所有细节,您将得到如下信息:
nmem.flatMap[(Char, Char), Map[Char, Char]]{
case (digit: Char, str: String) =>
str.map[(Char, Char), Seq[(Char, Char)]]{
(ltr: Char) => (ltr, digit)
}
}
幸运的是,这不是必需的,因为可以自动推断所有这些类型。
答案 1 :(得分:0)
item <- collection
语法通常用于遍历集合中的每个项目。
一个简单的例子是:
for(mapping <- map){
println(mapping)
}
在您的情况下,这实际上是使用yield语法的嵌套for
循环。
默认情况下,它将创建一个List
并累积所有物品。
用更多的语法写可能会有所帮助:
val charCode : Map[Char,Char] = { // Cast our result to a Map of (Char, Char)
for ((digit, str) <- nmem; // for every key-value pair (Char, String) in nmem
ltr <- str) // for every ltr (Char) in str (String)
yield ltr -> digit // add a new mapping to the map
}
您可以查看https://docs.scala-lang.org/../for-comprehensions.html以获得更多详细信息
答案 2 :(得分:-1)
第一个实际上 (digit, str) <- nmem
,从Map [String,String]中获取一个元组,下一个 ltr <- str
从中获取字符字符串。