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] 相互转换