And*_*yle 36 scala implicit traits
我正在设计一个类层次结构,它由一个基类和几个特征组成.基类提供了几种方法的默认实现,并且traits选择性地覆盖某些方法abstract override
,以便充当可堆叠的traits/mixins.
从设计的角度来看,这很有效,并映射到域,以便我可以从这里添加过滤函数(一个特征),带有来自此处的谓词(另一个特征)等.
但是,现在我想要一些我的特征来采用隐式参数.我很高兴从设计的角度来看这仍然有意义,并且在实践中不会让人感到困惑.但是,我不能说服编译器运行它.
问题的核心似乎是我无法为特征提供构造函数参数,因此可以将它们标记为隐式.在方法实现中引用隐式参数无法使用预期的"无法找到隐式值"消息进行编译; 我试图通过构建阶段(在实践中,它总是在范围内)"隐藏"隐含的方法,以便在方法中可用
implicit val e = implicitly[ClassName]
Run Code Online (Sandbox Code Playgroud)
但是(毫无疑问,你们很多人都希望)这个定义失败了同样的信息.
似乎这里的问题是我无法说服编译器用implicit ClassName
标志标记特征本身的签名,并强制调用者(即将特征混合到一个对象中的那些)来提供隐式.目前我的调用者正在这样做,但编译器没有在此级别进行检查.
是否有任何方法可以将特征标记为在施工时需要某些隐含物?
(如果不是,这还没有实现,还是有更深层次的原因,为什么这是不切实际的?)
Ale*_*nov 16
实际上,我之前经常想要这个,但我想出了这个想法.你可以翻译
trait T(implicit impl: ClassName) {
def foo = ... // using impl here
}
Run Code Online (Sandbox Code Playgroud)
to [EDITED:原始版本没有为其他方法提供隐式访问]
trait T {
// no need to ever use it outside T
protected case class ClassNameW(implicit val wrapped: ClassName)
// normally defined by caller as val implWrap = ClassNameW
protected val implWrap: ClassNameW
// will have to repeat this when you extend T and need access to the implicit
import implWrap.wrapped
def foo = ... // using wrapped here
}
Run Code Online (Sandbox Code Playgroud)
Pau*_*per 14
这是不可能的.
但是您可以使用implicitly
Scala的类型推断来尽可能轻松.
trait MyTrait {
protected[this] implicit def e: ClassName
}
Run Code Online (Sandbox Code Playgroud)
然后
class MyClass extends MyTrait {
protected[this] val e = implicitly // or def
}
Run Code Online (Sandbox Code Playgroud)
简洁,甚至不需要在扩展类中编写类型.
Bla*_*ade 11
我遇到过这个问题几次,确实有点烦人,但不是太多.摘要成员和参数通常是做同样事情的两种替代方式,各有利弊; 对于具有抽象成员的特征并不太不方便,因为无论如何你还需要另一个类来实现这个特征.*
因此,您应该在特征中简单地使用抽象值声明,以便实现类必须为您提供隐式.请参阅以下示例 - 它正确编译,并显示了实现给定特征的两种方法:
trait Base[T] {
val numT: Ordering[T]
}
/* Here we use a context bound, thus cannot specify the name of the implicit
* and must define the field explicitly.
*/
class Der1[T: Ordering] extends Base[T] {
val numT = implicitly[Ordering[T]]
//Type inference cannot figure out the type parameter of implicitly in the previous line
}
/* Here we specify an implicit parameter, but add val, so that it automatically
* implements the abstract value of the superclass.
*/
class Der2[T](implicit val numT: Ordering[T]) extends Base[T]
Run Code Online (Sandbox Code Playgroud)
我展示的基本思想也出现在Knut Arne Vedaa的答案中,但我试图制作一个更引人注目且更方便的例子,不再使用不需要的功能.
*这不是特质不能接受参数的原因 - 我不知道.我只是在争论这种限制在这种情况下是可以接受的.
归档时间: |
|
查看次数: |
23140 次 |
最近记录: |