隐式函数类型

隐式函数类型表示的是带隐式参数的函数的类型。例如:

type Contextual[T] = implicit Context => T

隐式函数类型的值与接受隐式参数的方法一样,接受隐式参数。例如:

implicit ctx: Context = ...

def f(x: Int): Contextual[Int] = ...

f(2)    // is expanded to f(2)(ctx)

反过来说,如果一个表达式预期的类型 E 是一个函数函数类型 implicit (T_1, ..., T_n) => U,并且 E 尚未是隐式函数值,那么 E 会被重写转换为一个隐式函数值

implicit (x_1: T1, ..., x_n: Tn) => E

名称 x_1, ..., x_n 是任意的。例如,接着刚才的定义,

def g(arg: Contextual[Int]) = ...

g(22)      // is expanded to g { implicit ctx => 22 }

g(f(2))    // is expanded to g { implicit ctx => f(2)(ctx) }

g(implicit ctx => f(22)(ctx)) // is left as it is

隐式函数类型有着相当强的表现力。例如这样的下面是用“构建器模式”构造一个表的例子:

table {
  row {
    cell("top left")
    cell("top right")
  }
  row {
    cell("botttom left")
    cell("bottom right")
  }
}

这个设计是通过定义允许通过 add 方法添加元素的类 TableRow 实现的:

class Table {
  val rows = new ArrayBuffer[Row]
  def add(r: Row): Unit = rows += r
  override def toString = rows.mkString("Table(", ", ", ")")
}

class Row {
  val cells = new ArrayBuffer[Cell]
  def add(c: Cell): Unit = cells += c
  override def toString = cells.mkString("Row(", ", ", ")")
}

case class Cell(elem: String)

tablerowcell 构建器方法可以利用隐函数类型定义,以避免样板管道代码。

def table(init: implicit Table => Unit) = {
  implicit val t = new Table
  init
  t
}

def row(init: implicit Row => Unit)(implicit t: Table) = {
  implicit val r = new Row
  init
  t.add(r)
}

def cell(str: String)(implicit r: Row) =
  r.add(new Cell(str))

这样的代码会被自动拓展为下面的代码:

table { implicit $t: Table =>
  row { implicit $r: Row =>
    cell("top left")($r)
    cell("top right")($r)
  }($t)
  row { implicit $r: Row =>
    cell("botttom left")($r)
    cell("bottom right")($r)
  }($t)
}

参考

想要了解更多信息,请参见博客文章

results matching ""

    No results matching ""