我想提出另一种解决这个问题的方法。
根据我对你模型的理解,你真正需要做的是确定要执行正确的open
逻辑的远程存储位置。
因此,你只需要提供隐式证据,例如像这样:
sealed trait StorageTag extends Product with Serializable
implicit case object Gcs extends StorageTag
implicit case object S3 extends StorageTag
sealed trait StorageFile[T <: StorageTag] extends Product with Serializable {
def bucket: String
def path: String
}
final case class GcsFile(bucket: String, path: String) extends StorageFile[Gcs.type]
final case class S3File(bucket: String, path: String) extends StorageFile[S3.type]
sealed trait StorageConfig[T <: StorageTag] extends Product with Serializable {
def keyPath: String
}
final case class GcsConfig(keyPath: String) extends StorageConfig[Gcs.type]
final case class S3Config(keyPath: String) extends StorageConfig[S3.type]
def open[T <: StorageTag](storageFile: StorageFile[T], storageConfig: StorageConfig[T])
(implicit tag: T):String = tag match {
case S3 =>
s"S3 -> bucket: '${storageFile.bucket}', path: '${storageFile.path}' | config keyPath: '${storageConfig.keyPath}'"
case Gcs =>
s"Gcs -> bucket: '${storageFile.bucket}', path: '${storageFile.path}' | config keyPath: '${storageConfig.keyPath}'"
}
现在,您可以这样调用方法。
open(S3File(bucket = "bucket", path = "path"), S3Config(keyPath = "keyPath"))
open(GcsFile(bucket = "bucket", path = "path"), GcsConfig(keyPath = "keyPath"))
open(S3File(bucket = "bucket", path = "path"), GcsConfig(keyPath = "keyPath"))
请注意,这种方法仅在所有
StorageFiles
和
StorageConfigs
具有相同属性的情况下才有效。如果不是这种情况,您可以尝试以下内容:
但请注意,此代码并非完全类型安全,可能会被欺骗
sealed trait StorageTag extends Product with Serializable
implicit case object Gcs extends StorageTag
implicit case object S3 extends StorageTag
sealed trait StorageFile[T <: StorageTag] extends Product with Serializable
final case class GcsFile(bucket: String, path: String, id: Int) extends StorageFile[Gcs.type]
final case class S3File(bucket: String, path: String) extends StorageFile[S3.type]
sealed trait StorageConfig[T <: StorageTag] extends Product with Serializable
final case class GcsConfig(keyPath: String, name: String) extends StorageConfig[Gcs.type]
final case class S3Config(keyPath: String) extends StorageConfig[S3.type]
def open[T <: StorageTag](storageFile: StorageFile[T], storageConfig: StorageConfig[T])
(implicit tag: T): String = tag match {
case S3 =>
val S3File(bucket, path) = storageFile
val S3Config(keyPath) = storageConfig
s"S3 -> bucket: '${bucket}', path: '${path}' | config keyPath: '${keyPath}'"
case Gcs =>
val GcsFile(bucket, path, id) = storageFile
val GcsConfig(keyPath, name) = storageConfig
s"Gcs -> bucket: '${bucket}', path: '${path}', id: $id | config keyPath: '${keyPath}', name: 'name'"
}
open(S3File(bucket = "bucket", path = "path"), S3Config(keyPath = "keyPath"))
open(GcsFile(bucket = "bucket", path = "path", id = 0), GcsConfig(keyPath = "keyPath", name = "name"))
open(S3File(bucket = "bucket", path = "path"), GcsConfig(keyPath = "keyPath", name = "name"))
open(
GcsFile(bucket = "bucket", path = "path", id = 0).asInstanceOf[StorageFile[StorageTag]],
GcsConfig(keyPath = "keyPath", name = "name").asInstanceOf[StorageConfig[StorageTag]]
)(S3.asInstanceOf[StorageTag])
StorageTag
的作用是什么?我发现你根本没有使用它。 - Mahmoud Hanafy