gpt4 book ai didi

scala - 无法在列表中获取通用对象的类型

转载 作者:行者123 更新时间:2023-12-01 03:07:45 26 4
gpt4 key购买 nike

我有以下特点:

trait Storage[C <: Config] {
def get(name: String, version: Int): Option[C]
def list: List[(String, String)]
def register(config: C): Boolean
}

我想创建以下类:
class MultiStorage[C <: Config](storages: List[Storage[_ <: C]]) extends Storage[C] {
def get(name: String, version: Int): Option[C] = {...}
def list: List[(String, String)] = {...}
def register(config: C) = {...}

如果不清楚,意思就是一个 MultiStorage存储类型 C 的元素(或子类型)在几个存储中,每个存储都包含单一类型的元素。

我正在与泛型斗争来实现注册方法。这个想法是,根据我要注册的对象类型,我需要选择正确的存储来注册,例如:
def register(config: C) = {
storages.foreach(s => {
if (typeOf(s) is Storage[C]) { // same type of config
s.register(config)
return
}
})
}

我用泛型和类型标签做了几次尝试,但没有什么有用的在这里分享。我可能在想我需要添加另一个类型标签来区分我在寄存器中收到的内容和声明为存储类型的内容。

我尝试过的一个想法是在 Storage 中有一个方法返回类型:
protected def getType()(implicit tag: TypeTag[C]): universe.Type = typeOf[C]

但在调用方我能够得到类似 _$1 的结果,老实说,我不明白这是什么意思。

另一种尝试是使用 shapeless ,但在这种情况下,我不确定是否有可能在 HList 中包含任意数量的元素的多存储贮存

最佳答案

运行时类需要可用,例如:

class Config
class FooConfig extends Config
class BarConfig extends Config

trait Storage[C <: Config] {
val ctag: ClassTag[C]

def get(name: String, version: Int): Option[C]
def list: List[(String, String)]
def register(config: C): Boolean
}

class FooStorage(implicit val ctag: ClassTag[FooConfig]) extends Storage[FooConfig] {
override def get(name: String, version: Int): Option[FooConfig] = ???

override def list: List[(String, String)] = ???

override def register(config: FooConfig): Boolean = ???
}

class BarStorage(implicit val ctag: ClassTag[BarConfig]) extends Storage[BarConfig] {
override def get(name: String, version: Int): Option[BarConfig] = ???

override def list: List[(String, String)] = ???

override def register(config: BarConfig): Boolean = ???
}


class MultiStorage[C <: Config](storages: List[Storage[_ <: C]])(implicit val ctag: ClassTag[C]) extends Storage[C] {
def get(name: String, version: Int): Option[C] = ???

def list: List[(String, String)] = ???

def register(config: C): Boolean = {
storages.foreach(storage => {
if (storage.ctag.runtimeClass.isAssignableFrom(config.getClass)) {

}
})
???
}
}

由于 trait 不能有构造函数参数,隐式类标签需要在每个实现 trait 的类中重复。如果您的类结构允许 Storage作为一个抽象类,可以减少样板的数量:
abstract class Storage[C <: Config](implicit val ctag: ClassTag[C]) {

def get(name: String, version: Int): Option[C]
def list: List[(String, String)]
def register(config: C): Boolean
}

class FooStorage extends Storage[FooConfig] {
override def get(name: String, version: Int): Option[FooConfig] = ???

override def list: List[(String, String)] = ???

override def register(config: FooConfig): Boolean = ???
}

关于scala - 无法在列表中获取通用对象的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55079296/

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