范型问题讨论

joachimz 2009-12-23
(非实际问题,仅仅为学习FP与 范型,理解scala)

为了实现Fluent的模式,所有方法最后都需要返回一个this,方便连续的调用,类似


x.max(100).notNull ...
所有方法都得这么做:


def max(m: Int) = {
  maxSize = m
  this
}
def setNullable(b: Boolean) = {
  allowNull = b
  this
}
...


为了简便我学着FP的做法,抽象一个方法returnSelf
然后,所有方法都简化为
class T {

  def max(m: Int) = returnSelf(maxSize = m)
  def setNullable(b: Boolean) = returnSelf(allowNull = b)
  // ....

protected def returnSelf(f: => Unit)= {
  f
  this
}

}

然后问题就来了,当这个对象被继承时,例如SubT增加新方法,但由于returnSelf返回的是父对象,Fluent被打破,即使重载returnSelf都不可行。大家有什么解决办法?

另外,我也尝试把这个独立为一个trait来处理,但继承的时候依然遇到问题

trait SelfContinue[T] {
	self : T =>
	type A >: T
	
	def returnSelf(f: => Unit): A = {
		f
		this
	}
}



没辙了,大家是否有好的建议?谢谢
night_stalker 2009-12-23
掩面路过 …… 为了对泛型搞反射,做过 n 多尝试,均失败 ……

不过可以这样:
case class SelfContinue[T](t: T) {
  def returnSelf(f: => Unit) = {
    f
    t
  }
}

class A {
  private val SC = SelfContinue(this)
  import SC._
  def a = returnSelf {
    println("a")
  }
}

class B extends A {
  private val SC = SelfContinue(this)
  import SC._
  def b = returnSelf {
    println("b")
  }
}


至于 A 中定义的方法,返回的值 scala 是不会自动认出它是个 B 的。

(new B b) a
(new B a).asInstanceOf[B] b


ps: this 明显比 returnSelf 容易写 …… faint ....
case class Faint[T](t: T) {
  def ft(f: => Unit) = {f;t}
}

class A {
  private val FT = Faint(this)
  import FT._
  def a = ft {
    println("a")
  }
}

class B extends A {
  private val FT = Faint(this)
  import FT._
  def b = ft {
    println("b")
  }
}


再 ps:感觉 ft 不够喜感,或者叫 orz,有首尾连接之意:
def a = orz {
  println("o_O")
}
Eastsun 2009-12-28
呵呵,把方法的返回类型都声明为this.type 试试
night_stalker 2009-12-28
黑科技啊 ……
http://scalada.blogspot.com/2008/02/thistype-for-chaining-method-calls.html
truekbcl 2009-12-29
当你用泛型的时候,不要想着这样用继承。
Global site tag (gtag.js) - Google Analytics