我正在嘗試創建不同配置的映射,其中每個配置都有一個給定的關鍵物件和一些選項,例如
FirstConfig可以是:FirstConfigOptionAFirstConfigOptionB
SecondConfig可以是:SecondConfigOptionASecondConfigOptionB
- ...
而且我在 setter 函式的一般型別和簽名方面遇到問題,因此它在編譯時檢查我是否提供了正確的物件,例如
// 1. this should compile normally
set(FirstConfig, FirstConfigOptionA)
// 2. should NOT compile due to `SecondConfigOptionA` parameter not being a valid option for `FirstConfig`
set(FirstConfig, SecondConfigOptionA)
到目前為止,我的嘗試仍然允許編譯上面的第二種情況。
abstract sealed class Configuration
trait OptionKey[T <: Configuration] {}
trait OptionVariant[T <: Configuration] {}
// First Config
trait FirstConfig extends Configuration
object FirstConfigKey extends OptionKey[FirstConfig];
object FirstConfigOptionA extends OptionVariant[FirstConfig]
object FirstConfigOptionB extends OptionVariant[FirstConfig]
// Second Config
trait SecondConfig extends Configuration
object SecondConfigKey extends OptionKey[SecondConfig];
object SecondConfigOptionA extends OptionVariant[SecondConfig]
object SecondConfigOptionB extends OptionVariant[SecondConfig]
def set[T](k: OptionKey[T], v: OptionVariant[T]): Unit = {}
set(FirstConfigKey, FirstConfigOptionA)
set(FirstConfigKey, SecondConfigOptionA) // This still compiles
我也嘗試過使用具有類似結果的列舉:
object FirstConfig extends Enumeration {
type FirstConfig = Value
val FirstConfigOptionA, FirstConfigOptionB = Value
}
object SecondConfig extends Enumeration {
type SecondConfig = Value
val SecondConfigOptionA, SecondConfigOptionB = Value
}
def set(k: Enumeration, v: Enumeration#Value): Unit = {}
set(FirstConfig, FirstConfig.FirstConfigOptionA)
set(FirstConfig, SecondConfig.SecondConfigOptionA) // This still compiles
表達配置與其可用選項之間的這種關系的正確方法是什么,或者應該是什么set簽名來強制執行它?
uj5u.com熱心網友回復:
使用這樣的路徑相關型別怎么樣:
trait Configuration {
sealed trait OptionKey
val key: OptionKey
sealed trait OptionVariant
}
object Configuration {
def set(config: Configuration)(variant: config.OptionVariant): Unit = {
println(s"${config} - ${config.key} - ${variant}")
}
}
case object FirstConfig extends Configuration {
private case object FirstConfigKey extends OptionKey
override final val key: OptionKey = FirstConfigKey
case object FirstConfigOptionA extends OptionVariant
case object FirstConfigOptionB extends OptionVariant
}
case object SecondConfig extends Configuration {
private case object SecondConfigKey extends OptionKey
override final val key: OptionKey = SecondConfigKey
case object SecondConfigOptionA extends OptionVariant
case object SecondConfigOptionB extends OptionVariant
}
您可以在這里看到它按預期作業。
uj5u.com熱心網友回復:
為什么需要將它們存盤為鍵/值對?您可以將其表示為代數資料型別:
enum FirstConfig:
case OptionA
case OptionB
enum SecondConfig:
case OptionA
case OptionB
enum Config:
case First(value: FirstConfig)
case Second(value: SecondConfig)
def set(config: Config): Unit = …
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/426110.html
上一篇:如何為RecyclerView配接器創建一個包裝器,該包裝器將接受任何實作RecyclerView.Adapter<RecyclerView.ViewHolder>的配接器
