为什么我们不能从私有扩展类型中获得公共类型?

时间:2017-09-05 05:09:51

标签: kotlin

如果我试试这个:

sealed class Attributes

data class Attributes1(
    val prop1: String
) : Attributes()

private data class IMyType<A>(
    val attributes: A
) where A: Attributes

typealias MyType1 = IMyType<Attributes1>

...我收到错误:'public'typealias以扩展类型IMyType 公开'private'。

防止这种情况的原因是什么?

注意:使用Kotlin 1.1.4

修改1

我理解什么是类型,我理解这些限制的含义。

我所问的是为什么需要这些限制。

如果您考虑我的示例代码...我希望MyType1(以及其他人)可以在此文件之外访问,但我不希望使用原始/通用IMyType在这个档案之外。

这不是一个合法的用例吗?

2 个答案:

答案 0 :(得分:1)

根据定义,typealias是为现有类型提供替代名称。因此,您无法按类型提升现有类型的可见性。

从类型的grammar开始,如果要在代码中使用typealias,则必须确保typealias的可见性低于或等于现有类型的可见性。例如:

internal class Bar

private typealias PrivateFoo = Bar

internal typealias InternalFoo = Bar

//v--- error
public typealias PublicFoo = Bar

答案 1 :(得分:0)

类型别名的可见性应与相应类型相同或更严格。

当您在文件中将IMyType声明为private时,IMyType是一个文件专用类,只能在该kotlin文件中访问。如果您为MyType1声明公开类型别名IMyType,则IMyType保密是没有意义的,因为MyType1可以随处访问。所以,这是禁止的。

来自Kotlin's doc

  

类型别名不会引入新类型。它们等同于相应的基础类型。在代码中添加typealias Predicate<T>并使用Predicate<Int>时,Kotlin编译器始终将其扩展为(Int) -> Boolean

拥有typealias的主要目的是为现有类型提供替代名称。在您的情况下,IMyTypeMyType1都指向同一个类。由于IMyType打算私有,因此您无法在文件外部访问MyType1IMyType

未介绍显示新类型的示例:

//Kotlin code
fun acceptMyType1(type: MyType1) {}

//Decompiled code, MyType1 is not used
public static final void acceptMyType1(@NotNull IMyType type) {
    Intrinsics.checkParameterIsNotNull(type, "type");
}

Sidetracked问题:您也不能通过公共子类expose a private super class