Scala、Array[Int] 和 Array[Option[Int]] 中的类型不匹配

Posted

技术标签:

【中文标题】Scala、Array[Int] 和 Array[Option[Int]] 中的类型不匹配【英文标题】:Type Mismatch in scala, Array[Int] and Array[Option[Int]] 【发布时间】:2017-09-23 08:16:08 【问题描述】:

首先,我是 Scala 新手,如果以下问题过于简单,敬请见谅。

我编写了以下代码来查找我在地图中的数组中提供的键的值。

def stringToCountMap(inputArray: Array[String], inputMap:Map[String,Int]) : Array[Int] = 
    return inputArray.map(x => inputMap.get(x))

我收到以下错误,

type mismatch;
 found   : Array[Option[Int]]
 required: Array[Int]
 return inputArray.map(x => inputMap.get(x))

问题: 1) 谁能解释什么是 Option[Int]? 2)我的错误是什么?

提前致谢。

【问题讨论】:

请注意,您可以使用:t(或:type,如果您更喜欢冗长的话)在Scala REPL 中examine 表达式的类型,您可以使用它来检查function's type ::t inputMap.get _(在定义一个合适的inputMap之后)。 我会试试这个。谢谢。 【参考方案1】:

Option 是 Scala 的option type(也称为nullable type)。它表示该值可能不存在的情况。

考虑一个不包含请求键的映射。您将如何处理对密钥的请求?一种选择是导致错误,例如抛出异常。另一种是返回一个表示没有值的特殊值。 Map.get 执行后者,使用 Option 作为特殊类型,None 作为值。这意味着Map.get 的返回类型不是映射的值类型(Int),而是应用于值类型(Option[Int])的Option

要更正类型声明,请更改返回类型:

def stringToCountMap(inputArray: Array[String], inputMap:Map[String,Int]) : Array[Option[Int]] = 
    inputArray.map(x => inputMap.get(x))

你可以省略stringToCountMap的返回类型,让类型推断来处理它:

def stringToCountMap(inputArray: Array[String], inputMap:Map[String,Int]) = 
    inputArray.map(x => inputMap.get(x))

因此,输入映射中缺少的键会通过:

scala> stringToCountMap(Array("a", "def"), Map("a" -> 1, "bc" -> 2))
res0: Array[Option[Int]] = Array(Some(1), None)

【讨论】:

【参考方案2】:

Option[T]T 类型值的包装器。它的目的是防止NullPointerException,您可能从 Java 中知道。 Option[T] 类型的值可能是 None,顾名思义,它是一个不代表任何内容的对象,也可能是 Some(x: T),它代表一个现有值。

inputMap(x) 返回一个Option[Int],因为您无法保证x 键存在于inputMap 中。如果是,则返回Some(value: Int),否则返回None

调用stringToCountMap(Array("a", "b", "c"), Map("a" -> 1, "c" -> 2)) 得到Array(Some(1), None, Some(2))

如果您想要Array[Int],则可以执行inputArray.map(x => inputMap.getOrElse(x, 0)).get 之类的操作。 getOrElse方法有两个参数,第一个是key,第二个是默认值。 inputArray.map(x => inputMap.get(x).getOrElse(0)) 具有相同的效果,因为在 Option 上调用 getOrElse(value) 要么解开 Some 对象,要么返回默认值。

现在,stringToCountMap(Array("a", "b", "c"), Map("a" -> 1, "c" -> 2)) 的结果是 Array(1, 0, 2)

您可能还想省略输入数组中缺少的键。在这种情况下,您可以使用inputArray.flatMap(x => inputMap.get(x))flatMap 是一个类似于map 的函数,但顾名思义,它严格返回平面集合。例如,在 Array[Array[Int]] 上调用 flatMap(x => x) 将在单行中返回二维数组中所有值的 Array。 在这里,Option 也是一个集合。如果它是Some 类型,它包含单个值,如果它是None,它是一个空集合。因此,在结果数组中,您将只有映射中存在的键的值,而映射中不存在的键将被跳过。

现在,stringToCountMap(Array("a", "b", "c"), Map("a" -> 1, "c" -> 2)) 的结果是 Array(1, 2)

【讨论】:

我理解这个概念。谢谢。【参考方案3】:

首先,在scala中不需要使用'return'来返回任何值。

def stringToCountMap(inputArray: Array[String], inputMap:Map[String,Int])  = 
     inputArray.map(x => inputMap.get(x))

当你从 Map 中获取 key 的值时,它会在 Option 中返回结果。 例如:

scala> val map  = Map(1-> "a",2 -> "b")
map: scala.collection.immutable.Map[Int,String] = Map(1 -> a, 2 -> b)

scala> map.get(1)
res0: Option[String] = Some(a)

scala> map.get(3)
res1: Option[String] = None

当您尝试获取不存在的键值时。在 java 中,您遇到过 NullPointerException。所以当没有值时,它返回 None 以避免异常。 欲了解更多信息refer 在您的方法中,您将返回类型指定为 Array[Int] 但函数返回 Array[Option[Int]] 这就是它引发编译错误的原因。

【讨论】:

在 SO 上,表达感谢的最佳方式是vote。

以上是关于Scala、Array[Int] 和 Array[Option[Int]] 中的类型不匹配的主要内容,如果未能解决你的问题,请参考以下文章

Scala 库将数字(Int、Long、Double)与 Array[Byte] 相互转换

RDD[Array[Int]] 上的 Scala Reduce() 操作

9-1 Array

利用Scala深入剖析经典排序算法之选择排序

如何比较scala中的两个数组?

Scala--数组类型