Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 理解Scala中的字符串和映射方法_String_Scala_Dictionary - Fatal编程技术网

String 理解Scala中的字符串和映射方法

String 理解Scala中的字符串和映射方法,string,scala,dictionary,String,Scala,Dictionary,我编写了以下简单示例来了解map方法的工作原理: object Main{ def main (args : Array[String]) = { val test = "abc" val t = Vector(97, 98, 99) println(test.map(c => (c + 1))) //1 Vector(98, 99, 100) println(test.map(c => (c + 1).toChar))

我编写了以下简单示例来了解map方法的工作原理:

object Main{
  def main (args : Array[String]) = {
    val test = "abc"
    val t = Vector(97, 98, 99)
    println(test.map(c => (c + 1)))               //1 Vector(98, 99, 100)
    println(test.map(c => (c + 1).toChar))        //2 bcd
    println(t.map(i => (i + 1)))                  //3 Vector(98, 99, 100)
    println(t.map(i => (i + 1).toChar))           //4 Vector(b, c, d)
  };
}

我不太明白为什么bcd打印在
//2
。因为Scala将每个字符串都视为一个
Seq
,所以我认为
test.map(c=>(c+1.toChar)
应该生成另一个
Seq
。正如
//1
所建议的
向量(b,c,d)
。但正如你所看到的,它没有。为什么?它实际上是如何工作的?

当您使用map时,会发生以下情况:
[List | Seq | etc].map([eachement]=>[do something])

map对左侧变量的每个元素应用一些操作:
“abc”。map(字母=>字母+1)
将向
字符串的每个元素添加1。
字符串
abc
的每个元素在这里称为“字母”(类型为
Char

“abc”是一个字符串,就像C++一样,它被当作一个字符数组。但是由于
test
是String类型,map函数也会给出一个字符串

我尝试了以下方法:

val test2 : Seq[Char] = "abc"
但是我仍然得到一个String类型的结果,我猜Scala会自动地将Seq[Char]转换为String


我希望有帮助

这是Scala集合的一项功能(在本例中,字符串被视为字符集合)。真正的解释是相当复杂的,涉及到对类型类的理解(我想,这就是为什么在评论中提到Haskell),但简单的解释并不难

关键是,Scala集合库的作者非常努力地避免代码重复。例如,
String
上的
map
函数实际上是在这里定义的:
scala.collection.TraversableLike#map
。另一方面,这种任务的简单方法会使
map
返回
TraversableLike
,而不是调用
map
的原始类型(它是
字符串
)。这就是为什么他们提出了一种方法来避免代码重复和不必要的类型转换或过于一般的返回类型

基本上,Scala collections方法(如
map
)生成的类型与调用它时的类型尽可能接近。这是通过使用名为
CanBuildFrom
的类型类实现的。
地图的完整签名如下所示:

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That

关于什么是typeclass有很多解释,
CanBuildFrom
。我建议先看看这里。另一个很好的解释是:

虽然它是用Haskell编写的,但这是我在Scala中学习FP的方式。我建议你购买和阅读。或者,我建议,这是在线免费的。@KevinMeredith你真的认为需要学习Haskell才能理解Scala字符串是如何工作的吗?出于这个原因,我只是发表评论,而不是回答。为了理解
map
,我的观点和经验是,首先理解函数式编程的基础是值得的-因为
map
是FP的基础。@KevinMeredith。。。特别是为了解释Scala的
CanBuildFrom
,它在Haskell?@VictorMoroz中根本不存在——我发现的第25章(Scala集合的体系结构)很好地解释了
CanBuildFrom
。还有-维克托,你打电话给我说的关于
CanBuildFrom
的事也很有道理。我应该阅读这个问题,而不是假设它是关于理解FP中的
map
。这个例子是,即使测试被声明为Seq[Char],它仍然被转换为字符串+1。真正简短的答案是Scala的收集操作像Smalltalk一样保留类型,而不是像Java一样保留最一般的类型,.NET(
IEnumerable
)或Ruby(
Array
)。