scala:类成员的类型推断

问题描述 投票:0回答:0

考虑以下代码:scastie

class A           {              }
class B extends A { def m = true }

trait X           { def obj : A     }
class Y extends X { def obj = new B }

val y = new Y
y.obj.m // Compiles in scala2, does not compile in scala3.

y.obj
的类型是什么?

似乎在scala2

y.obj
B
,而在scala3
y.obj
A
! 结果查找
y.obj.m
在 scala2 中编译,但在 scala3 中不编译。

显然,在 scala3 中,

def obj: A
中的抽象成员
X
的类型优先于
Y
中的较窄类型推断。

正如预期的那样,

y.obj
是一个
B
当:

class Y /* extends X */ { def obj     = new B } // member is not previously declared
class Y    extends X    { def obj : B = new B } // type is forced by ascription

这看起来是良性的,直到有人使用 透明内联方法 从宏中返回一些类型信息。

  • scala2scala3 之间的差异是预期的吗?
  • 意图是什么?
  • 有解决方法吗?

这是一个更具描述性的片段:scastie

class A
class B extends A:
  def m = true

transparent inline def choose(b: Boolean): A =
  if b then new A else new B


class X:
  def obj1 : A
  def obj2 : A
  def obj3 : A

class Y extends X:
  def obj1     = choose(true)  // type A
  def obj2     = choose(false) // type A ( from X.this.obj2 )
  def obj3 : B = choose(false) // type B ( from ascription  )
  def obj4     = choose(false) // type B ( from inference   )

val y = new Y
y.obj1.m // compile error     EXPECTED
y.obj2.m // compile error   UNEXPECTED
y.obj3.m // compiles          EXPECTED
y.obj4.m // compiles          EXPECTED
type-inference scala-3
© www.soinside.com 2019 - 2024. All rights reserved.