无法编译 Kotlin 中另一个 class 中的密封 classes:无法访问 '<init>' 它是私有的
Sealed classes inside another class in Kotlin can't be compiled: cannot access '<init>' it is private
如果我使用 docs 中的示例,
class SomeActivity : AppCompatActivity() {
sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
}
编译不通过,报错:
Cannot access '<init>', it is private in 'Expr'.
但是,将它移到封闭的 class 之外使其编译:
sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
class SomeActivity : AppCompatActivity() {
}
为什么会这样?这是有意的行为吗?文档似乎没有提到这一点。
来自文档:
A sealed class is abstract by itself, it cannot be instantiated
directly and can have abstract members.
Sealed classes are not allowed to have non-private constructors (their
constructors are private by default).
我猜你应该如何使用这个例子:
fun main(args: Array<String>) {
val c = Const(5.0)
val s = Sum(Const(1.0), Const(3.0))
println(eval(c))
println(eval(s))
}
sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
fun eval(expr: Expr): Double = when(expr) {
is Const -> expr.number
is Sum -> eval(expr.e1) + eval(expr.e2)
NotANumber -> Double.NaN
// the `else` clause is not required because we've covered all the cases
}
在 Kotlin 1.0 中,sealed 功能相当受限。为了
例如,所有的 subclasses 必须是嵌套的,而 subclass 不能变成 a
data class(data classes 将在本章后面介绍)。 Kotlin 1.1 放松
限制并允许您在任何地方定义密封 classes 的子classes
同一个文件。
在给定的示例中,到目前为止是不允许的。可能在以后的发行版本中,他们会放宽此限制。
但是,您可以这样做:
class SomeActivity {
sealed class Expr {
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
}
}
是的,事实证明这是有意为之的行为。根据the proposal allowing non-nested subclasses:
Proposal: allow top-level subclasses for a top-level sealed class in the same file.
For a non top-level sealed class all subclasses should be declared inside it. So, for such classes nothing changes.
您想要的场景被列为悬而未决的问题。在 https://youtrack.jetbrains.com/issue/KT-13495 有票。目前似乎没有人在研究它。在提案的讨论中,开发者说:
如果我使用 docs 中的示例,
class SomeActivity : AppCompatActivity() {
sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
}
编译不通过,报错:
Cannot access '<init>', it is private in 'Expr'.
但是,将它移到封闭的 class 之外使其编译:
sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
class SomeActivity : AppCompatActivity() {
}
为什么会这样?这是有意的行为吗?文档似乎没有提到这一点。
来自文档:
A sealed class is abstract by itself, it cannot be instantiated directly and can have abstract members.
Sealed classes are not allowed to have non-private constructors (their constructors are private by default).
我猜你应该如何使用这个例子:
fun main(args: Array<String>) {
val c = Const(5.0)
val s = Sum(Const(1.0), Const(3.0))
println(eval(c))
println(eval(s))
}
sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
fun eval(expr: Expr): Double = when(expr) {
is Const -> expr.number
is Sum -> eval(expr.e1) + eval(expr.e2)
NotANumber -> Double.NaN
// the `else` clause is not required because we've covered all the cases
}
在 Kotlin 1.0 中,sealed 功能相当受限。为了 例如,所有的 subclasses 必须是嵌套的,而 subclass 不能变成 a data class(data classes 将在本章后面介绍)。 Kotlin 1.1 放松 限制并允许您在任何地方定义密封 classes 的子classes 同一个文件。 在给定的示例中,到目前为止是不允许的。可能在以后的发行版本中,他们会放宽此限制。 但是,您可以这样做:
class SomeActivity {
sealed class Expr {
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
}
}
是的,事实证明这是有意为之的行为。根据the proposal allowing non-nested subclasses:
Proposal: allow top-level subclasses for a top-level sealed class in the same file.
For a non top-level sealed class all subclasses should be declared inside it. So, for such classes nothing changes.
您想要的场景被列为悬而未决的问题。在 https://youtrack.jetbrains.com/issue/KT-13495 有票。目前似乎没有人在研究它。在提案的讨论中,开发者说: