gpt4 book ai didi

Scala:使用协变 Field[+T] 访问属性

转载 作者:行者123 更新时间:2023-12-01 12:25:46 24 4
gpt4 key购买 nike

我正在使用一个自定义的不可变实体类,它使用的键是扩展 Field[+T] 的 case 对象,其中 T 是协变的。这是有道理的,因为 Field[Stream[Int]] 应该能够被视为 Field[Seq[Int]]。

object ProblemWithCovariant {

sealed trait Field[+T]
case object _username extends Field[String]
case object _email extends Field[String]
case object _age extends Field[Byte]

case class Entity(attrs: Map[Field[Any], Any]) {
def apply[T](field: Field[T]): T = attrs(field).asInstanceOf[T]
def set[T](field: Field[T])(value: T): Entity = copy(attrs = attrs.updated(field, value))
}

def main(args: Array[String]): Unit = {
val user = Entity(Map.empty)
.set(_username)("John")
.set(_age)(23)

val username: String = user(_username) // alright
val ageInt: Int = user(_age) // compile error
}

}

然而,当我尝试检索 Byte 值并将其分配给 Int 字段时,这会导致编译错误。我知道 Byte 不是 Int 的子类型,它们唯一的关系是隐式转换。令我惊讶的是,在上面的示例中没有调用此转换,编译器现在要求我传递一个 Field[Int]!

经过一段时间的试验,我意识到我可以简单地显式提供类型,例如 val ageInt: Int = user[Byte](_age)。虽然这有效,但它使我的代码比我希望的更冗长。有什么办法可以更改 Entity.apply 的签名,使其符合 field 参数的类型?

最佳答案

def apply[T, U](field: Field[U])(implicit ev: U => T): T = 
ev(attrs(field).asInstanceOf[U])

有效。

关于Scala:使用协变 Field[+T] 访问属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39943061/

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