为了引入更多的类型安全性,我们既可以使用提供的标记类型,也可以shapeless创建一个扩展的类AnyVal.使用一个而不是另一个有什么区别和优势/劣势?
例:
trait CountryCodeTag
type CountryCode = String @@ CountryCodeTag
class CountryCode(code: String) extends AnyVal
Run Code Online (Sandbox Code Playgroud)
type CountryCode = String @@ CountryCodeTag
+ String @@ CountryCodeTag是一个子类型String,即所有方法String都可以直接使用:countryCode.toUpperCase.
- String @@ CountryCodeTag可以在某些String预期的地方意外使用,即它的类型安全性较低.
- 创造新价值有点尴尬:"a".asInstanceOf[String @@ CountryCodeTag]或val tagger = new Tagger[CountryCodeTag]; tagger("a").
- 对Shapeless的依赖(虽然这可以手动完成).
class CountryCode(code: String) extends AnyVal
+它更安全.
- String可以通过一些额外的努力获得方法:
class CountryCode(val code: String) extends AnyVal
new CountryCode(countryCode.code.toUpperCase)
Run Code Online (Sandbox Code Playgroud)
要么
class CountryCode(val code: String) extends AnyVal
object CountryCode {
def unapply(...) = ...
}
countryCode match { case CountryCode(code) => new CountryCode(code.toUpperCase) }
Run Code Online (Sandbox Code Playgroud)
要么
case class CountryCode(code: String) extends AnyVal
countryCode.copy(code = countryCode.code.toUpperCase)
Run Code Online (Sandbox Code Playgroud)
+创造新价值更自然:new CountryCode("a").
+没有额外的依赖(它是普通的Scala).
| 归档时间: |
|
| 查看次数: |
728 次 |
| 最近记录: |