如何将HOCON配置转换为Case class数组?类型安全配置取值报错
Alright, let's break down how to resolve this issue and get your HOCON config mapped to the Array[ConfigData] you want. The error you're hitting comes down to Scala's type inference struggling to figure out the type of the config elements without a little help.
Step 1: Confirm Your Dependencies
First, make sure you have the Typesafe Config library (the standard for parsing HOCON in Scala) added to your project. For sbt, that looks like:
libraryDependencies += "com.typesafe" % "config" % "1.4.2" // Use the latest stable version available
Step 2: The Correct Conversion Code
Your ConfigData case class is already set up correctly:
case class ConfigData(name: String, value: String)
The problem with your initial code is that Scala can't automatically infer the type of the elements in the ConfigList (since it's a Java-backed collection). We just need to explicitly specify the parameter type in our mapping function, or help the compiler infer it properly. Here's the working code:
import com.typesafe.config.{Config, ConfigFactory, ConfigList} import scala.jdk.CollectionConverters._ // Load your HOCON config (this looks for application.conf by default) val config = ConfigFactory.load() // Retrieve the list from config val mapConfigList: ConfigList = config.getList("mapConfig") // Convert to Array[ConfigData] val configDataArray: Array[ConfigData] = mapConfigList .asScala // Convert Java ConfigList to Scala Iterable .map { (cfg: Config) => // Explicitly specify cfg is a Config type to fix inference ConfigData( name = cfg.getString("name"), value = cfg.getString("value") ) } .toArray
Why This Fixes the Error
The "missed parameter type for..." error occurs because the Java ConfigList's map method doesn't provide enough type information for Scala's compiler to guess that each element is a Config instance. By explicitly writing (cfg: Config) in the anonymous function, we tell the compiler exactly what type we're dealing with, letting it resolve the rest of the mapping correctly.
Alternative: For-Comprehension Style
If you prefer a more readable for-comprehension approach, this works too (and still avoids the type inference issue):
val configDataArray = for { cfg <- mapConfigList.asScala name = cfg.getString("name") value = cfg.getString("value") } yield ConfigData(name, value) val finalArray: Array[ConfigData] = configDataArray.toArray
After running either of these, you'll get the exact Array[ConfigData] you're expecting:Array(ConfigData(AAA,BBBB), ConfigData(CCC,DDD), ConfigData(EEE,FFF))
内容的提问来源于stack exchange,提问作者Mohan

