在Scala编程第3版中 . 我对代码感到困惑 "WithPrintWriter(new File("date.txt"), a => a.println(new java.util.Date) )}"
1 import java.io._
2
3 object WithPrintWriter1 {
4 def withPrintWriter(file: File, op: PrintWriter => Unit) {
5 val writer = new PrintWriter(file)
6 try {
7 op(writer)
8 } finally {
9 writer.close()
10 }
11 }
12 def main(args: Array[String]) {
13 withPrintWriter(
14 new File("date.txt"),
15 a => a.println(new java.util.Date)
16 )
17 }
18 }
我使用scala的术语来解释函数调用中的 a=> a.println(new java.util.Date)
,这是一个函数文字,参数是a并映射到a.println(new java.util.Date)函数 . 但是withPrintWriter函数的原型需要两种类型,第一种是File,它适用于新文件("date.txt"),而另一种是函数值,它接受一个PrintWriter类,返回一个Unit(不是有趣的结果) . 我们传递给第二个参数是 a => a.println(new java.util.Date)
,是什么类型的 . 函数需要一个as参数,函数体是a.println(new java.util.Date) . 你觉得它太奇怪了吗? scala编译器如何完成这种代码?
1 import java.io._
2
3 object WithPrintWriter1 {
4 def withPrintWriter(file: File, op: PrintWriter => Unit) {
5 val writer = new PrintWriter(file)
6 try {
7 op(writer)
8 } finally {
9 writer.close()
10 }
11 }
12 def main(args: Array[String]) {
13 withPrintWriter(
14 new File("date.txt"),
15 _ => _.println(1))
16 }
17 }
上面的代码会产生错误 . scala_test / WithPrintWriter1.scala:15:错误:缺少扩展函数的参数类型((x $ 2)=> x $ 2.println(1))_ => _.println(1)) . 为什么占位符会产生错误 . 这是scala编译器无法推断出类型的原因吗?但是我们可以将sub_line字符替换为任何没有类型的字符,如'a','b','c'等 . 我感到很困惑 .
任何帮助将不胜感激,谢谢 .
我尝试了这个代码,它添加了PrintWriter类型 . 没关系 . Maybe the type can be omitted.
1 import java.io._
2
3 object WithPrintWriter1 {
4 def withPrintWriter(file: File, op: PrintWriter => Unit) {
5 val writer = new PrintWriter(file)
6 try {
7 op(writer)
8 } finally {
9 writer.close()
10 }
11 }
12 def main(args: Array[String]) {
13 withPrintWriter(
14 new File("date.txt"),
15 (a: PrintWriter) => a.println(new java.util.Date)
16 )
17 }
18 }
虽然我用_像这样(:PrintWriter)替换a,这将产生错误 . scala_test / WithPrintWriter2.scala:15:错误:扩展函数缺少参数类型((x $ 2)=> x $ 2.println(new java.util.Date()))(:PrintWriter)=> _.println(new java.util.Date)这很有趣 . 救命 .
1 回答
...实际上是...的简写
编译器已经推断出类型,因为它知道
withPrintWriter()
方法的第二个参数应该是PrintWriter => Unit
类型,即函数类型PrintWriter
输入并且没有任何意义,Unit
,结果 .这不起作用,
_ => _.println(1)
,因为下划线具有特殊含义 . 要正确使用它,你会写:_.println(1)
在这种情况下,单个下划线是简写:
a => a