【问题标题】:Union type with upper bound具有上限的联合类型
【发布时间】:2014-08-14 18:41:23
【问题描述】:

我正在遵循这个问题的公认答案中提出的技术 How to define "type disjunction" (union types)? 以支持对方法的多类型参数进行类型检查。

隐含的“证据”

@implicitNotFound(msg="Only String, Array[Byte] and InputStream are supported")
  sealed class Input[T]
  object Input{
    implicit object ByteArrayWitness extends Input[Array[Byte]]
    implicit object StringWitness extends Input[String]
    implicit object InputStreamWitness extends Input[InputStream]
  }

API 方法

def foo[T: Input](param: T) =
  param match {
    case x: String => //...
    case x: Array[Byte] => //...
    case x: InputStream => //...
    case _ => throw new UnsupportedOperationException(s"not implemented for type ${param.getClass}")
  }

问题

这会编译

foo("test")
foo(Array[Byte](123.toByte))

但这不是(因为它不是具体的InputStream

foo(new ByteArrayInputStream("abc".getBytes("UTF-8")))

我必须将它转换为确切的超类型才能使其工作(编译)

foo(new ByteArrayInputStream("abc".getBytes("UTF-8")).asInstanceOf[InputStream])

有没有办法改变

    implicit object InputStreamWitness extends Input[InputStream]

所以它是所有扩展InputStream的证据?我感觉有一些上限 <: 符号可以插入某个地方,我真的不知道在哪里......

或者这就是来自上述问题的最高投票答案的“疯狂的 lambda 演算东西”来拯救?

【问题讨论】:

    标签: scala types


    【解决方案1】:

    使Input contra 变体在T 类型中像:Input[-T],表示如果A 是B 的超类型,那么Input[B] 是Input[A] 的超类型(反向“继承”) .在您的情况下,这仅意味着 Input[InputStream] 知道如何处理所有子类输入类型InputStream(如ByteArrayInputStream

    我真的很喜欢 Rex Kerr 在this 问题中对逆变的解释。但是还有很多其他的

    【讨论】:

    • 啊...我现在觉得很傻...虽然我变得更聪明了,但讽刺的是。谢谢!
    猜你喜欢
    • 2021-06-04
    • 2022-12-18
    • 2019-10-11
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    相关资源
    最近更新 更多