我可以模仿Scala SIP-18-syle进口吗?

时间:2015-07-27 22:15:01

标签: scala

Scala SIP 18提供了一种强制用户提供import语句以使用某些高级或不安全语言功能的方法。例如,要使用higher kinded types,您需要

keeplimits

或者您会收到编译器警告,告诉您正在使用高级功能。

有没有什么方法可以在我自己的库中重现或模仿这种行为?例如,我可能有:

import scala.language.higherKinds

我让trait MongoRepository[E <: Entity] { val casbahCollection: com.mongodb.casbah.MongoCollection } public公开底层集合给用户,以备他们需要时。但它真的不是我希望我的用户做的事情,因为它是一个漏洞的抽象。所以我想强迫他们做这样的事情:

casbahCollection

在做这样的事情之前:

import my.library.mongo.leakyAbstraction

有可能吗?有没有什么方法可以提供类似的行为,比在文档中放置一个大丑陋的警告更有效?

1 个答案:

答案 0 :(得分:8)

您可以使用隐式伪造它,类似于Await.resultscala.concurrent的工作方式。

首先创建一个sealed trait代表一个&#34; permit&#34;直接访问你的DAO:

@implicitNotFound("Import my.library.mongo.leakyAbstraction to directly access Mongo")
sealed trait CanAccessMongo

然后是一个扩展它的对象:

implicit object leakyAbstraction extends CanAccessMongo

这些必须在同一个文件中。通过使CanAccessMongo密封,同一文件外的代码将无法扩展它。

然后在MongoRepository中设置cashbahCollection一个函数(将val更改为def)。您可能想要一个实际创建它的私有val,但我们需要该函数来限制访问。

def cashbahCollection(implicit permit: CanAccessMongo) = ...

现在,您的图书馆用户必须将leakyAbstraction带入范围才能调用该功能。如果他们没有,他们将收到implicitNotFound中指定的错误消息。

明显的缺点是你的所有库代码都必须在范围内有leakyAbstraction