限制Scala参数中的特定类型?

时间:2015-01-28 00:08:56

标签: scala types

有时我会遇到一种情况,我特别想限制发送给函数的内容,但接受几乎任何其他类型。这可能在Scala中吗?例如,此代码在运行时处理我的问题 - 接受除Option对象之外的任何类型T.编译器可以抓住它吗?谢谢

def apply[T:TypeTag](t: T): TaggedOption[T] =
  t match {
    case o: Option[_] =>
      // ensure this can't be created
      throw new Exception("This function doesn't work with Options")
    case other =>
      TaggedOption_(Some(t), PowerTag[T])
  }

2 个答案:

答案 0 :(得分:4)

可以限制类型参数:

scala> trait <:!<[A, B]
defined trait $less$colon$bang$less

scala> implicit def nsub[A, B] : A <:!< B = null
nsub: [A, B]=> <:!<[A,B]

scala> implicit def nsubAmbig1[A, B >: A] : A <:!< B = ???
nsubAmbig1: [A, B >: A]=> <:!<[A,B]

scala> implicit def nsubAmbig2[A, B >: A] : A <:!< B = ???
nsubAmbig2: [A, B >: A]=> <:!<[A,B]

scala> def notOption[A](a: A)(implicit ev: A <:!< Option[_]) = a
notOption: [A](a: A)(implicit ev: <:!<[A,Option[_]])A

scala> notOption(1)
res0: Int = 1

scala> notOption(List(""))
res1: List[String] = List("")

scala> notOption(Option(1))
<console>:14: error: ambiguous implicit values:
 both method nsubAmbig1 of type [A, B >: A]=> <:!<[A,B]
 and method nsubAmbig2 of type [A, B >: A]=> <:!<[A,B]
 match expected type <:!<[Option[Int],Option[_]]
              notOption(Option(1))
                       ^

scala> notOption(Some(1))
<console>:14: error: ambiguous implicit values:
 both method nsubAmbig1 of type [A, B >: A]=> <:!<[A,B]
 and method nsubAmbig2 of type [A, B >: A]=> <:!<[A,B]
 match expected type <:!<[Some[Int],Option[_]]
              notOption(Some(1))
                       ^

scala> notOption(None)
<console>:14: error: ambiguous implicit values:
 both method nsubAmbig1 of type [A, B >: A]=> <:!<[A,B]
 and method nsubAmbig2 of type [A, B >: A]=> <:!<[A,B]
 match expected type <:!<[None.type,Option[_]]
              notOption(None)
                       ^

暗示使Option案例含糊不清。有关代码应如何工作的更详细说明,请参阅以下thread on scala-user

答案 1 :(得分:1)

注意:这不是您问题的解决方案,而是您问题的可能解决方案。

您可以先解开它们来处理Option对象。

def apply[T:TypeTag](t: T): TaggedOption[T] =
  t match {
    case Some(x) =>
      apply(x)
    case None => TaggedNone // or whatever
    case other =>
      TaggedOption_(Some(t), PowerTag[T])
  }
}
相关问题