限制 Scala 参数中的特定类型?
Restrict specific type in Scala paramaters?
有时我会遇到这样一种情况,我特别想限制可以发送给函数的内容,但几乎接受任何其他类型。这在 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])
}
注意:这不是您问题的解决方案,而是您问题的可能解决方案。
您可以先解包来处理 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])
}
}
可以限制类型参数:
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.
有时我会遇到这样一种情况,我特别想限制可以发送给函数的内容,但几乎接受任何其他类型。这在 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])
}
注意:这不是您问题的解决方案,而是您问题的可能解决方案。
您可以先解包来处理 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])
}
}
可以限制类型参数:
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.