1

如果我有

sealed class Foo<A> {
  data class Bar<A>(val value: Int): Foo<A>()
}

并且我想Bar<Int>使用运算符将​​构造函数称为隐式 lambda ::,然后以下均不被接受为有效语法:

  • Foo<Int>::Bar<Int>
  • ::Foo.Bar<Int>
  • ::(Foo.Bar<Int>)(编译器告诉我这个语法是为将来使用而保留的)。

如果我将嵌套类构造函数显式导入到作用域中,我可以引用它

import com.package.Foo.Bar

这使我可以::Bar为构造函数和Bar<Int>::value属性 getter 编写代码。但是我必须对每个嵌套的构造函数都这样做,这有点破坏了使用::运算符来节省打字的优势。

有没有我遗漏的符号可以让我避免导入所有嵌套的类名和构造函数?

编辑

我最初的示例不涉及泛型,结果证明我在我正在处理的实际代码中遇到的问题过于简单化了,它确实使用了泛型。

事实证明,对于没有泛型参数的嵌套类,Foo::Bar符号实际上是有效的,所以我最初的问题有一个错误的前提。但是,不可能在泛型类中创建对构造函数的可调用引用。这记录在以下错误报告中:https ://youtrack.jetbrains.com/issue/KT-15952

4

2 回答 2

1

外卡进口呢?

import com.package.Foo.*
于 2020-03-04T07:10:00.657 回答
1

这是语言设计中的一个已知错误:https ://youtrack.jetbrains.com/issue/KT-15952

但是,此错误报告确实使我找到了使用类型别名的另一种解决方法,这等效于添加别名导入,但其优点是您可以将别名放在所需的位置,甚至在模块之间共享它。总之,这是迄今为止我所知道的两个唯一可行的解​​决方案:

// Method one: Import Foo.Bar

import Foo.Bar as BarImported

sealed class Foo<A> {
  data class Bar<A>(val value: A): Foo<A>()
}

val ctor: (Int) -> Foo<Int> = ::BarImported
val getter: (BarImported<Int>) -> Int = BarImported<Int>::value


// Method two: Alias Foo.Bar
typealias BarAlias<A> = Foo.Bar<A>

val ctor2: (Int) -> Foo<Int> = ::BarAlias
val getter2: (Foo.Bar<Int>) -> Int = BarAlias<Int>::value
于 2020-03-04T08:41:09.097 回答