2017-09-05 75 views
0

如果我试试这个:为什么我们不能从私有扩展类型中获得公共类型?

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> 

...我得到的错误:在扩张型IMyType'公' typealias自曝 '私有'。

什么是预防这个问题的原因?

注:使用科特林1.1.4

编辑1

我明白别名是什么,我的理解到位的限制的影响。

我在问的是为什么这些限制需要在那里。

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

这不是一个合法用例吗?

回答

0

类型别名的可见性应该与相应的类型相同或更受限制。

当您在文件中声明IMyTypeprivate时,IMyType是一个文件私有类,它只能在该kotlin文件中访问。如果您为IMyType声明了公开类型别名MyType1,那么IMyType是私有的,因为MyType1可以在任何地方访问。所以,这是被禁止的。

Kotlin's doc

Type aliases do not introduce new types. They are equivalent to the corresponding underlying types. When you add typealias Predicate<T> and use Predicate<Int> in your code, the Kotlin compiler always expand it to (Int) -> Boolean .

具有typealias的主要目的是为现有类型提供替代名称。在你的情况下,IMyTypeMyType1指的是同一个类。由于IMyType打算保密,因此您不能在文件外部访问IMyTypeMyType1。不引入

为例,说明新类型:

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

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

牵制的问题:你不能expose a private super class通过公开子类也。

+0

请参阅我的第一个编辑。 – pleasedesktop

+0

@pleasedesktop他们指的是同一个班级,但没有引入新的类型。我已经添加了示例来说明情况。 – BakaWaii

0

按照定义typealias是为现有类型提供替代名称。所以你不能通过typealias提升现有类型的可见性。

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

internal class Bar 

private typealias PrivateFoo = Bar 

internal typealias InternalFoo = Bar 

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

请参阅我的第一个编辑。 – pleasedesktop

+0

@pleasedesktop嗨,这是因为我尝试通过'typealias'暴露客户端无法看到并使用的类。 –

+0

客户端将能够看到它,但他们将无法使用它,这正是我所追求的行为。我的扩展类型是通用的,但我不想公开泛型,我想通过typealiases公开非泛型。 – pleasedesktop

相关问题