Kotlin 嵌套在泛型父类中的类构造函数的函数引用

Kotlin 嵌套在泛型父类中的类构造函数的函数引用,kotlin,Kotlin,如果我有 sealed class Foo<A> { data class Bar<A>(val value: Int): Foo<A>() } 它允许我为构造函数编写::Bar,为属性getter编写Bar::value。但是我必须对每个嵌套构造函数都这样做,这有点挫败了使用:操作符来保存键入的优势 是否有一个我遗漏的符号,可以避免导入所有嵌套的类名和构造函数 编辑 我最初的例子并没有涉及泛型,这是对我正在处理的实际代码中的问题的过度简化,它确实使用泛

如果我有

sealed class Foo<A> {
  data class Bar<A>(val value: Int): Foo<A>()
}
它允许我为构造函数编写
::Bar
,为属性getter编写
Bar::value
。但是我必须对每个嵌套构造函数都这样做,这有点挫败了使用
操作符来保存键入的优势

是否有一个我遗漏的符号,可以避免导入所有嵌套的类名和构造函数

编辑 我最初的例子并没有涉及泛型,这是对我正在处理的实际代码中的问题的过度简化,它确实使用泛型


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

我很确定Kotlin将
Foo
Foo.Bar
视为完全不相关的类,因此导入
Foo
不会自动让您访问
Bar
。事实上,您必须单独导入它;我找不到有关的详细信息,但是…

通配符导入如何

import com.package.Foo.*

这是语言设计中的一个已知错误:

但是,这个bug报告确实让我找到了另一个使用类型别名的解决方法,这相当于添加别名导入,但它的优点是,您可以将别名放在您想要的地方,甚至可以在模块之间共享它。总而言之,这是迄今为止我所知道的两个唯一可行的解决方案:

// 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
//方法一:导入Foo.Bar
以BarImported的形式导入食物棒
密封级Foo{
数据类栏(val值:A):Foo()
}
val-ctor:(Int)->Foo=::BarImported
val getter:(BarImported)->Int=BarImported::value
//方法二:别名Foo.Bar
typealias BarAlias=Foo.Bar
val ctor2:(Int)->Foo=::BarAlias
val getter2:(Foo.Bar)->Int=BarAlias::value

这会有些效果,但问题是使用嵌套类的动机是避免名称冲突。例如,
sealed class Foo{data class A(…):Foo()}
sealed class Bar{data class A(…):Bar()}
。两个
A
构造函数的导入必须使用别名来避免名称冲突,而这在通配符中是不可能的。事实并非如此。我可以只导入
Foo
,并访问它的所有嵌套类。特别是,我可以编写
Foo.Bar(42)
来实例化嵌套的
Bar
类。但是我不能使用
符号为
构造函数创建匿名lambda。
// 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