我想实现类,它描述了有关设置某个选项值的操作。我想让选项的值类型取决于选项类型。我想做到这一点:
case class SetOptionMessage[T <: BaseOptionType](
option: T
value: Option[T#ValueType]
)
abstract class BaseOptionType {
type ValueType
}
object SomeBooleanOption extends BaseOptionType {
final type ValueType = Boolean
}
但是当我尝试使用这样的类时:
val msg = SetOptionMessage(SomeBooleanOption, Some(true))
我收到了编译错误:
Error:(15, 43) type mismatch;
found : Some[Boolean]
required: Option[?#ValueType]
SetOptionMessage(SomeBooleanOption, Some(true))
^
如何正确引用嵌套类型?
答案 0 :(得分:5)
case class SetOptionMessage[V, T <: BaseOptionType{ type ValueType = V }](
option: T,
value: Option[V]
)
val msg = SetOptionMessage(SomeBooleanOption, Some(true))
// msg: SetOptionMessage[Boolean,SomeBooleanOption.type] = SetOptionMessage(SomeBooleanOption$@2e93ebe0,Some(true))
case class SetOptionMessage[V, T <: BaseOptionType](
option: T,
value: Option[V])(implicit e: V =:= T#ValueType)
SetOptionMessage(SomeBooleanOption, Some(true))
// SetOptionMessage[Boolean,SomeBooleanOption.type] = SetOptionMessage(SomeBooleanOption$@2e93ebe0,Some(true))
SetOptionMessage(SomeBooleanOption, None)
// SetOptionMessage[SomeBooleanOption.ValueType,SomeBooleanOption.type] = SetOptionMessage(SomeBooleanOption$@2e93ebe0,None)
您无法在此解决方案中使用case class
。
class SetOptionMessage[T <: BaseOptionType](option: T)(val value: Option[T#ValueType])
val msg = new SetOptionMessage(SomeBooleanOption)(Some(true))
// SetOptionMessage[SomeBooleanOption.type] = SetOptionMessage@7f216e0c
msg.value
// Option[SomeBooleanOption.ValueType] = Some(true)
不要使用它。
答案 1 :(得分:1)
ValueType
是一种与路径相关的类型。这意味着您无法使用#
访问它,SetOptionMessage
只能引用非路径相关的类型。
尝试将case class SetOptionMessage[T <: BaseOptionType](val option: T,
private val _value: Option[Any]) {
val value = _value.asInstanceOf[Option[option.ValueType]]
}
更改为:
val msg = SetOptionMessage(SomeBooleanOption, Some("hello"))
但是,您不应该使用此解决方案(请参阅下面的注释)。我保留答案未被发现,以揭露其问题。
注意强>
正如@senia在他的回答中指出的那样,这是最糟糕的解决方案,因为它依赖于类强制转换。这个演员提出了一些限制,因为这个SO答案中突出显示: https://stackoverflow.com/a/6690611/1893995
表达式:
{{1}}
不仅会编译,而且甚至会在运行时崩溃。