![](/img/trans.png)
[英]Scala: How to use a `MatchesRegex` refinement with a regex containing a backtick (refined library)?
[英]How to ensure type safety with Scala's Refined library when using the same predicate for refinement
我是 scala 和精炼库的新手,但我正在尝试基于 UUID 创建两种精炼类型。
为此,我这样做了(注意:本例中的 Uuid 来自 eu.timepit.refined.string.Uuid):
type UuidPredicate = Uuid
type UuidA = String Refined UuidPredicate
type UuidB = String Refined UuidPredicate
但是,这似乎只创建别名,因此没有类型安全性。
因此,如果我有一个像Product(a UuidA, b UuidB)
这样的构造函数并继续执行以下操作:
val myUuid: UuidA = "9f9ef0c6-b6f8-11ea-b3de-0242ac130004"
val Product = Product(myUuid, myUuid)
它将正确编译和运行。 有没有办法确保不是这种情况? 如果一个变量被创建为一种类型,我怎样才能使它只用作那个特定的细化类型,即使类型基本相同?
最简单的就是引入不同的数据类型
case class UuidA(value: String Refined UuidPredicate)
case class UuidB(value: String Refined UuidPredicate)
你不能让UuidA
, UuidB
扩展AnyVal
因为Refined
已经扩展AnyVal
并且 Scala 不允许嵌套值类。
如果您希望避免使用UuidA
包装的运行时开销, UuidB
您可以尝试@newtype
正如@LuisMiguelMejíaSuárez建议的那样
import io.estatico.newtype.macros.newtype
@newtype case class UuidA(value: String Refined UuidPredicate)
@newtype case class UuidB(value: String Refined UuidPredicate)
或者尝试添加更多标签
import eu.timepit.refined.api.Refined
import eu.timepit.refined.string.Uuid
import eu.timepit.refined.auto._
import shapeless.tag
import shapeless.tag.@@
type UuidPredicate = Uuid
type UuidString = Refined[String, UuidPredicate]
type TagA
type TagB
type UuidA = UuidString @@ TagA
type UuidB = UuidString @@ TagB
case class Product(a: UuidA, b: UuidB)
val myUuid: UuidA = tag[TagA][UuidString]("9f9ef0c6-b6f8-11ea-b3de-0242ac130004")
// val product = Product(myUuid, myUuid) // doesn't compile
val myUuid1: UuidB = tag[TagB][UuidString]("9f9ef0c6-b6f8-11ea-b3de-0242ac130004")
val product1 = Product(myUuid, myUuid1) // compiles
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.