我有以下定义:
trait Xode[+R] {
type S = Option[R]
}
case class AXode(a: Int) extends Xode[Int]
case class BXode(b: String) extends Xode[String]
object xtore {
private var m: Map[Xode[_], Xode[_]#S] = Map()
def put[A <: Xode[_]](k: A)(v: A#S) {
m += k -> v
}
}
执行以下操作时,不会引发错误,但我希望AXode#S为Option [Int]。
xtore.put(AXode(5))(Some("apples")) // <-- no error
可能会发生A
被推断为Xode[_]
,然后Xode[_]#S
变为Option[_]
。我可以用类型参数表达我的意图吗?
当R是抽象类型成员而不是类型参数实现时,它按预期工作。或依赖方法类型和键入v: k.S
也有帮助。还有其他构造吗?
答案 0 :(得分:1)
X[_]
表示X[Any]
。特别是,您的映射不会将值类型与Xode
类型构造函数的wild-carded参数上的键类型相关联。此外,在put
中,如果需要,scalac可以将A
的类型扩展为Xode[Any]
。免责声明:我不是100%肯定我在写什么
以下内容拒绝xtore.put(AXode(5))(Some("apples"))
并接受xtore.put(AXode(5))(Some(0))
。请注意,您还需要捕获Xode
的类型参数,而不是OP中的Xode[_]
版本。我完全不理解它,可能有一个更简单的解决方案。
def put[A,B[X] <: Xode[X]](k: B[A])(v: B[A]#S) {
m += k -> v
}