Coo*_*bou 6 scala method-chaining
我想在这些问题中实现方法链接:
但是,我希望一旦使用了"属性",它就不能再使用了.例如,假设我有一个类"Myclass",我想允许使用定义"foo"和定义"bar"最多一次,我不关心最终的返回类型.从而:
val c = new Myclass
c foo //ok !
c foo bar // ok!
c foo foo // refuse to compile
c foo bar foo //refuse to compile
Run Code Online (Sandbox Code Playgroud)
我在这个问题上挣扎了一段时间,我的视力开始变得模糊!我尝试使用隐式类,但是,他们是否需要解析没有使用关联属性的对象,我无法找到他们是否需要通过从对象可用属性中删除它来"使用"该属性,以及再说一次,我怎么也找不到.
我目前正在使用反射API进行搜索,但对我来说它仍然有点模糊.
帮助将不胜感激!=)
sen*_*nia 14
请参阅James Iry的Haskell和Scala中的幻影类型.
您还可以使用类型安全的构建器模式:
trait TTrue
trait TFalse
@annotation.implicitNotFound(msg = "Cannot call same method twice.")
sealed abstract class =^=[From, To]
object =^= {
private val singleton_=^= = new =^=[Any, Any]{}
implicit def tpEquals[A]: A =^= A = singleton_=^=.asInstanceOf[A =^= A]
}
class Myclass[TFoo, TBar, TBuz] private(){
def foo(implicit e: TFoo =^= TFalse) = new Myclass[TTrue, TBar, TBuz]
def bar(implicit e: TBar =^= TFalse) = new Myclass[TFoo, TTrue, TBuz]
def buz(implicit e: TBuz =^= TFalse) = new Myclass[TFoo, TBar, TTrue]
}
object Myclass{
def apply() = new Myclass[TFalse, TFalse, TFalse]
}
Run Code Online (Sandbox Code Playgroud)
像这样使用
scala> Myclass().foo.bar.buz
res0: Myclass[TTrue,TTrue,TTrue] = Myclass@12ac706a
scala> Myclass().bar.buz.foo
res1: Myclass[TTrue,TTrue,TTrue] = Myclass@1e69dff6
scala> Myclass().foo.buz.foo
<console>:12: error: Cannot call same method twice.
Myclass().foo.buz.foo
^
Run Code Online (Sandbox Code Playgroud)