此Scala代码的功能样式

Osc*_*Ryz 9 coding-style scala

我的一个朋友正在学习Scala,并编写了这个简单的代码来跟踪文件中最长的行:

val longest = (filename:String) => {
  val is = new FileInputStream(filename)
  val buf = new Array[Byte](1024)
  var longest=0 //keep track of the longest line
  var lastPos=0
  var read=0
  try {
    read = is.read(buf)
    while (read > 0) {
      for (i<-0 until read) {
        if (buf(i) == '\n') {
          val size=i-lastPos-1
          lastPos=i
          if (size>longest) {
            longest=size
          }
        }
      }
      lastPos-=buf.length
      read=is.read(buf)
    }
  } finally {
    is.close()
  }
  longest
}
Run Code Online (Sandbox Code Playgroud)

我也是Scala的新手,但我很确定这个代码中有flatMaps和其他函数的空间.

有人可以发布这个功能版本吗?

Ben*_*mes 24

另一种实现方式:

def longest(filename: String) =
  Source.fromFile(filename).getLines.map(_.size).max
Run Code Online (Sandbox Code Playgroud)

简要说明:

  • getLines 返回文件中行的迭代器;
  • map(_.size),等效于map(line => line.size),返回行长度的新迭代器
  • max 返回最大的行长度.

  • 该文件只会迭代一次.当你调用`map`时,它不会从迭代器中提取任何值; 它存储`_.size`函数并创建一个新的迭代器,它将在调用*时将该函数应用于第一个迭代器*的每个输出.调用`max`最终会强制迭代. (4认同)

mis*_*tor 13

val longest = (filename: String) =>
  io.Source.fromFile(filename).getLines.maxBy(_.length).length
Run Code Online (Sandbox Code Playgroud)


Tom*_*icz 5

是的,这段代码非常迫切.在Scala中,粗略的等价物是(!):

def longest(fileName: String) = 
  Source.fromFile(fileName).getLines().max(Ordering.fromLessThan[String](_.size < _.size)).size
Run Code Online (Sandbox Code Playgroud)

猜猜提供一些解释不会有什么坏处:

def longest(fileName: String) = Source.
    fromFile(fileName).     //file contents abstraction
    getLines().     //iterator over lines
    max(        //find the max element in iterated elements
        Ordering.fromLessThan[String](_.size < _.size)  //however, use custom comparator by line size
    ).size  //max() will return the line, we want the line length
Run Code Online (Sandbox Code Playgroud)

当然,Scala中的TMTOWTDI.