首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么java.lang.Integer和java.lang.Double的最小上界被推断为非循环类型?

为什么java.lang.Integer和java.lang.Double的最小上界被推断为非循环类型?
EN

Stack Overflow用户
提问于 2011-11-13 10:11:27
回答 1查看 1.1K关注 0票数 16

考虑下面的代码:

代码语言:javascript
复制
val foo = if(true) 
            new java.lang.Double(4) 
          else
            new java.lang.Integer(4)

foo的推断类型为:

代码语言:javascript
复制
Number with Comparable[_ >: Double with Integer <: Number with 
  Comparable[_ >: Double with Integer <: Number]]

所以基本上编译器在边界上循环,并在第三次递归后中止。

为什么以下内容还不够呢?

代码语言:javascript
复制
Number with Comparable[_ >: Double with Integer <: Number]
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-11-13 21:25:18

不是答案,而是在REPL中隐式使用的一些线索。编译器不认为类型是相同的。推断的类型更具体:

代码语言:javascript
复制
// some type aliases to make reading easier
type Dx = java.lang.Double
type Ix = java.lang.Integer

// the type the compiler came up with:
type Inferred = Number with Comparable[
  _ >: Dx with Ix <: Number with Comparable[_ >: Dx with Ix <: Number]]

// your type:
type Soc = Number with Comparable[_ >: Dx with Ix <: Number]

检查类型别名是否正确:

代码语言:javascript
复制
val d = new java.lang.Double(4)
val i = new java.lang.Integer(4)
val foo: Soc = if (true) d else i
// foo: Soc = 4.0
val foo: Inferred = if (true) d else i
// foo: Inferred = 4.0

类型不同:

代码语言:javascript
复制
implicitly[Soc =:= Inferred] // error

您的类型是推断类型的超类型:

代码语言:javascript
复制
implicitly[Inferred <:< Soc] // ok
implicitly[Soc <:< Inferred] // error

因此,根据编译器的说法,它提出了一个更具体的类型-这将是正确的做法。请注意,可以像这样重新创建用例:

代码语言:javascript
复制
class N                     // like java.lang.Number

trait C[T]                  // like Comparable

class I extends N with C[I] // like java.lang.Integer
class D extends N with C[D] // like java.lang.Double

type DI = N with C[_ >: D with I <: N with C[_ >: D with I <: N]]
// DI is like the type inferred

type DI_SOC = N with C[_ >: D with I <: N] // your type

val foo: DI = if (true) new D else new I     // ok
val foo: DI_SOC = if (true) new D else new I // ok

implicitly[DI =:= DI_SOC] // error
implicitly[DI <:< DI_SOC] // DI_SOC super type of DI
implicitly[DI_SOC <:< DI] // error

所以我想知道我们是否可以创建一个是DI_SOC而不是DI的类,这将说明DIDI_SOC是不同的类型,并且您的类型不是最小上限。

好的,在走出电脑一小段时间后,再试一次。下面是一个不是DIDI_SOC

代码语言:javascript
复制
class A extends N with C[N]
implicitly[A <:< DI_SOC] // ok
implicitly[A <:< DI]     // error

适用于原始用例:

代码语言:javascript
复制
class Ax extends Number with Comparable[Number] {
  def doubleValue() = 0d
  def floatValue() = 0f
  def intValue() = 0
  def longValue() = 0L
  def compareTo(n: Number) = 0
}

implicitly[Ax <:< Soc]      // ok
implicitly[Ax <:< Inferred] // error

因此,SocInferred的类型是不同的,Ax证明了Number with Comparable[_ >: Double with Integer <: Number]不是最小上界。

换句话说,在Double with Integer <: ? <: Number之间有一些空间,但在Double with Integer <: ? <: Number with Comparable[_ >: Double with Integer <: Number]之间没有太多空间

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8109105

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档