package com.scathon.tech.basic.callbyname
import java.io.File
import scala.io.Source
import scala.util.control.NonFatal
object ByNameParameter {
def main(args: Array[String]): Unit = {
val path = "/Users/scathon/projects/scala/scala_lang/pom.xml"
manager(Source.fromFile(new File(path))) { source =>
println("start count lines.")
val lines = source.getLines().size
println(s"line count is: $lines")
}
println("=========greate split border==========")
// 测试resoure传名参数的加载时机
// 这里并不会对SourceWrapper.fromFile(path)理解进行求值,而是到了43行的时候才会进行求值。并且只会求值一次。
manager(SourceWrapper.fromFile(path)) { source =>
println("start count lines.")
val lines = source.getLines().size
println(s"line count is: $lines")
}
}
// 这里为了验证加载时机,所以对Source.formFile进行了一层包装。里里面打印日志
// 判断什么时候调用的fromFile方法。
object SourceWrapper {
def fromFile(path: String): Source = {
println("start load source...")
Source.fromFile(path)
}
}
}
object manager {
// 传名参数就是resource参数这种定义的方式,可以简单理解为调用时省略括号的函数。
def apply[R <: {def close(): Unit}, T](resource: => R)(f: R => T): Unit = {
var res: Option[R] = None
try {
println("first step in f")
// resource函数的调用是懒的,不是立即加载的。
res = Some(resource)
f(res.get)
} catch {
case NonFatal(e) => println(s"nonfatal error ${e.getMessage}")
} finally {
for (r <- res) {
println("release resource...")
r.close()
}
}
}
}
运行结果:
first step in f
start count lines.
line count is: 58
release resource...
=========greate split border==========
first step in f
start load source...
start count lines.
line count is: 58
release resource...