gpt4 book ai didi

scala - 为什么映射到 Scala 枚举的 ValueSet 不会更改值的类型?

转载 作者:行者123 更新时间:2023-12-02 01:04:44 26 4
gpt4 key购买 nike

我在 Scala 的 ValueSet 中发现了一些令人费解的行为。使用这样的枚举,

object MyEnum extends Enumeration{
val V1 = new MyEnum
val V2 = new MyEnum
class MyEnum extends Val
implicit def convertValue(v: Value): MyEnum = v.asInstanceOf[MyEnum]
}

MyEnum.values 从 Value 映射到 MyEnum 会生成另一个 ValueSet,该 ValueSet 在转换为数组时不会保留映射的类型。

val naiveMappedValues = MyEnum.values.map(
implicitly[MyEnum.Value => MyEnum.MyEnum]).toArray
// REPL prints: naiveMappedValues: Array[MyEnum.Value] = Array(V1, V2)

如果 MyEnum.values 首先被转换为列表,那么最终数组的类型是正确的。

val mappedValues = MyEnum.values.toList.map(
implicitly[MyEnum.Value => MyEnum.MyEnum]).toArray
// REPL prints: mappedValues: Array[MyEnum.MyEnum] = Array(V1, V2)

为什么会这样?为什么在映射值之前需要先将ValueSet转换为List?

最佳答案

MyEnum.values 返回一个 Enumeration.ValueSetValueSet 子类型 Set[Value]。当您在 ValueSet 上执行 map 时,它会尝试返回一个新的 ValueSet 给您,只要有新元素,它就可以返回是 Value 的子类型。但是,ValueSet 始终是 Set[Value],因此当元素向上转换回 Value 时,在 map 中完成的向下转换将被撤消。另一方面,List 有一个类型参数,因此您可以将 List[Value] 映射到 List[MyEnum]

所有这些魔法都由 map 所采用的 CanBuildFrom 控制。如果您使用 collection.breakOut,您可以强制 map 构建您想要的任何类型:

val fastMappedValues: Array[MyEnum.MyEnum] = MyEnum.values.map(
implicitly[MyEnum.Value => MyEnum.MyEnum])(collection.breakOut)

关于scala - 为什么映射到 Scala 枚举的 ValueSet 不会更改值的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23840986/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com