【问题标题】:Scala upper and lower type boundScala 上下类型界限
【发布时间】:2018-03-19 21:46:27
【问题描述】:

我很难在 scala 中找到同时施加上限和下限的方法。我需要创建一个泛型函数,其中类型参数既可散列(AnyRef 的子类型)又可空(Null 的超类型)。

我可以这样实现前者:

def foo[T <: AnyRef](t: T) = ???

而后者是这样的:

def bar[T >: Null)(t: T) = ???

有没有一种方法可以同时进行?谢谢。

【问题讨论】:

  • 一般来说,我不知道是否可以在两个方向上都有类型边界。但是在特定情况下,Scala中的Null的AnyRef超类型的所有子类型不都是吗?
  • 不,因为 Nothing 是 Null 的子类型,因此,它不会让我将 null 分配给以 AnyRef 的子类型为边界的类型的变量。
  • 嗯。有趣的。 @lambdista 的解决方案似乎对我有用(虽然我尝试过,但颠倒类型边界的顺序 def foo[T &lt;: AnyRef &gt;: Null]( t : T ) = ??? 没有)

标签: scala generics


【解决方案1】:

这个怎么样?

def foo[T >: Null <: AnyRef](t: T) = ???

它应该工作。那就是:

foo(42) // does not compile 
foo(null) // compiles
foo("hello") // compiles

【讨论】:

    【解决方案2】:

    任何属于AnyRef 子类的类型都可以分配值null,因此您不需要上限。

    def foo[T <: AnyRef](x: T) = x
    foo(null) // returns null
    

    也就是说,由于您需要能够对值进行哈希处理,因此应该注意,如果您尝试取消引用 null(例如 null.hashCode),您将得到一个 NullPointerException。例如:

    def foo[T <: AnyRef](x: T) = x.hashCode
    foo(null) // Throws an NPE
    

    此外,强烈反对在 Scala 程序中使用 null。考虑到这一切,我认为您可能真正想要的是这样的东西,它适用于任何类型:

    def foo[T](x: Option[T]) = x.hashCode
    def foo(None) // Works. None is equivalent to no value (and Option(null) == None).
    def foo(Some(1)) // Works. Note an Int isn't an AnyRef or nullable!
    def foo(Some("Hello, world!")) // Works
    def foo(Option(null)) // Works.
    def foo(Option(z)) // Works, where z can be any reference type value, including null.
    

    Option[T] 是一种处理未定义值(例如可空类型)的函数式方法,它适用于任何类型T

    【讨论】:

      猜你喜欢
      • 2015-10-15
      • 2013-10-13
      • 1970-01-01
      • 1970-01-01
      • 2014-01-21
      • 1970-01-01
      • 2020-07-22
      • 1970-01-01
      • 2021-04-23
      相关资源
      最近更新 更多