如何在Scala中声明一个返回自身的函数(或具有相同签名的另一个函数)?

时间:2013-11-20 10:31:25

标签: scala

首先是背景 - 我正在编写一些代码来解码从套接字接收的消息。套接字的性质意味着作为ByteString接收的这些消息可能与其他消息完整,截断或连接。消息本身被分成一个公共标题,其中包含随后的变量数据的长度。

我的计划是拥有读取消息部分的函数,例如第一次读取可以读取变量数据的长度,第二次读取可变数据本身。

当调用其中一个方法时,我希望它返回下一个操作,如果由于尚未接收到所需的所有数据而无法执行特定读取,则该操作可能是读取序列中的下一个逻辑操作或本身。

如果从套接字接收的数据完美框架,则读取操作将在readLengthreadData之间交替。但是,当从套接字以多个块读取数据时,读取操作可能遵循readLengthreadDatareadData模式。

希望这是有道理的。

我想做的是这样的事情(由于循环引用而无法编译):

type ReadFunction = (ByteBuffer) => ReadFunction

所以我可以声明这样的事情:

def readLength(buffer: ByteBuffer): ReadFunction = {

  if (buffer.limit - buffer.position > 4) {

    return readData(buffer.getInt)
  }
  else {

    return readLength
  }
}

def readData(length: Int)(buffer: ByteBuffer): ReadFunction = {

  if (buffer.limit - buffer.position > length) {

    val data: Array[Byte](size)
    buffer.get(data) 

    //process data

    readLength   
  }
  else {

    readData(length)
  }
}

现在我知道我可以(并且实际上已经)通过将读取操作定义为扩展公共特征并返回每个特征的类来解决这个问题,但这似乎相当不像Scala。

所以我的问题是 - 你如何定义一个可以返回的函数?

1 个答案:

答案 0 :(得分:4)

您无法在type声明中使用循环引用,但您可以在classtrait声明中使用它,如下所示:

implicit class ReadFunction(f: Int => ReadFunction) extends (Int => ReadFunction) {
  def apply(i: Int) = f(i)
}

lazy val read: ReadFunction = { i: Int => println(i); read }

scala> read(1)(2)(3)
1
2
3
res0: ReadFunction = <function1>
相关问题