我有很多类似的案例类,它们意味着不同的东西但具有相同的参数列表。
object User {
case class Create(userName:String, firstName: String, lastName: String)
case class Created(userName:String, firstName: String, lastName: String)
}
object Group {
case class Create(groupName:String, members: Int)
case class Created(groupName:String, members: Int)
}
鉴于这种设置,我厌倦了编写采用Create类型的参数并返回Created类型的参数的方法。我有大量的测试用例可以完成这类工作。
我可以写一个函数将一个case类转换成另一个。此功能会将User.Create
转换为User.Created
def userCreated(create: User.Create) = User.Create.unapply(create).map((User.Created.apply _).tupled).getOrElse(sys.error(s"User creation failed: $create"))
我必须为Group编写另一个这样的函数。 我真正想要的是一个泛型函数,它接受两种类型的case类和一个case类的对象并转换为另一个。像,
def transform[A,B](a: A):B
此外,此功能不应失败减少样板的目的。如果更容易使用,请随意为功能建议不同的签名。
答案 0 :(得分:10)
无形的救援!
您可以使用Shapeless的X509Certificate2 objCert = new X509Certificate2();
string accountName = "xxxxxstorage";
string accountKey = "qqqqqqqqqqqqqqqjt8DGAI6aBoBzdwwwwwwwwwwwwwzZg==";
StorageCredentials creds = new StorageCredentials(accountName, accountKey);
CloudStorageAccount account = new CloudStorageAccount(creds, useHttps: true);
// Create the blob client.
CloudBlobClient blobClient = account.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("certificate");
CloudBlockBlob blockBlob = container.GetBlockBlobReference("Certificate.p12");
byte[] certData;
// Save blob contents to a memorystream.
using (var stream = new MemoryStream())
{
blockBlob.DownloadToStream(stream);
certData = stream.ToArray();
}
objCert.Import(certData);
来创建案例类的通用表示,然后可以用它来完成您尝试执行的操作。使用Generic
,我们可以强制执行类型和参数名称。
LabelledGeneric
答案 1 :(得分:5)
为了记录,这是我设法实现的最简单的类型安全语法:
implicit class Convert[A, RA](value: A)(implicit ga: Generic.Aux[A, RA]) {
def convertTo[B, RB](gb: Generic.Aux[B, RB])(implicit ev: RA =:= RB) =
gb.from(ga.to(value))
}
它可以像这样使用:
case class Create(userName: String, firstName: String, lastName: String)
case class Created(userName: String, firstName: String, lastName: String)
val created = Create("foo", "bar", "baz").convertTo(Generic[Created])
与LabelledGeneric
同样可以实现更好的类型安全:
implicit class Convert[A, RA](value: A)(implicit ga: LabelledGeneric.Aux[A, RA]) {
def convertTo[B, RB](gb: LabelledGeneric.Aux[B, RB])(implicit ev: RA =:= RB) =
gb.from(ga.to(value))
}
val created = Create("foo", "bar", "baz").convertTo(LabelledGeneric[Created]))