为了账号安全,请及时绑定邮箱和手机立即绑定

如何定义“类型分离”(联合类型)?

如何定义“类型分离”(联合类型)?

如何定义“类型分离”(联合类型)?有一种方法建议处理重载方法的双重定义是将重载替换为模式匹配:object Bar {    def foo(xs: Any*) = xs foreach {        case _:String => println("str")       case _:Int => println("int")       case _ => throw new UglyRuntimeException()    }}这种方法要求我们提交对参数的静态类型检查。foo..如果能写的话会好得多object Bar {    def foo(xs: (String or Int)*) = xs foreach {       case _: String => println("str")       case _: Int => println("int")    }}我可以接近Either,但它很快就会变得丑陋,有两种以上的类型:type or[L,R] = Either[L,R]implicit def l2Or[L,R](l: L): L or R = Left(l)implicit def r2Or[L,R](r: R): L or R = Right(r)object Bar {    def foo(xs: (String or Int)*) = xs foreach {       case Left(l) => println("str")       case Right(r) => println("int")    }}它看起来像是一个通用的(优雅的,高效的)解决方案需要定义Either3, Either4..有谁知道实现同样目的替代解决方案吗?据我所知,Scala没有内置的“类型分离”。另外,上面定义的隐式转换是否潜伏在某个标准库中,以便我只需导入它们?
查看完整描述

3 回答

?
慕容708150

TA贡献1831条经验 获得超4个赞

嗯,在具体的案例中Any*,下面这个技巧不会起作用,因为它不会接受混合类型。但是,由于混合类型也不能处理重载,所以这可能是您想要的。

首先,使用您希望接受的类型声明一个类,如下所示:

class StringOrInt[T]object StringOrInt {
  implicit object IntWitness extends StringOrInt[Int]
  implicit object StringWitness extends StringOrInt[String]}

接下来,声明foo就像这样:

object Bar {
  def foo[T: StringOrInt](x: T) = x match {
    case _: String => println("str")
    case _: Int => println("int")
  }}

仅此而已。你可以打电话foo(5)foo("abc"),它会起作用的,但是试一试foo(true)就会失败。客户端代码可以通过创建StringOrInt[Boolean],除非,如兰德尔下面,你做StringOrIntsealed班级,等级。

它起作用是因为T: StringOrInt意味着有一个隐式参数StringOrInt[T],因为Scala在类型的伴生对象中查找,以查看是否存在使请求该类型的代码工作的隐式。


查看完整回答
反对 回复 2019-07-08
?
红糖糍粑

TA贡献1815条经验 获得超6个赞

下面是Rex Kerr编码联合类型的方法。直截了当!

scala> def f[A](a: A)(implicit ev: (Int with String) <:< A) = a match {
     |   case i: Int => i + 1
     |   case s: String => s.length     | }f: [A](a: A)(implicit ev: <:<[Int with String,A])Intscala> f(3)res0:
      Int = 4scala> f("hello")res1: Int = 5scala> f(9.2)<console>:9: error: Cannot prove that Int with String <:< Double.
       f(9.2)
        ^

资料来源:第27条评论这,这个MilesSabin的优秀博客文章提供了在Scala中编码联合类型的另一种方式。


查看完整回答
反对 回复 2019-07-08
  • 3 回答
  • 0 关注
  • 426 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信