Scala中的函数是实现其中一个FunctionN特征的对象.例如:
scala> def f(x: Int) = x * x
f: (x: Int)Int
scala> val ff = f _
ff: Int => Int = <function1>
scala> val fff: Function1[Int, Int] = f _
fff: Int => Int = <function1>
到现在为止还挺好.但是如果我们有一个带有名字参数的函数呢?它当然仍然实现了以下   FunctionN特征之一:
scala> def g(x: => Int) = x * x
g: (x: => Int)Int
scala> val gg = g _
gg: => Int => Int = <function1>
scala> gg.isInstanceOf[Function1[_, _]]
res0: Boolean = true
但究竟是什么类型的呢?它不是Function1[Int, Int]:
scala> val ggg: Function1[Int, Int] = g _
<console>:8: error: type mismatch;
 found   : => Int => Int
 required: Int => Int
       val ggg: Function1[Int, Int] = g _
                                      ^
也不是Function1[Function0[Int], Int]:
scala> val ggg: Function1[Function0[Int], Int] = g _
<console>:8: error: type mismatch;
 found   : => Int => Int
 required: () => Int => Int
       val ggg: Function1[Function0[Int], Int] = g _
                                                 ^
并且Function1[=> Int, Int]无法编译:
scala> val ggg: Function1[=> Int, Int] = g _
<console>:1: error: identifier expected but '=>' found.
       val ggg: Function1[=> Int, Int] = g _
                          ^
那是什么?
按名称非常有用,但在类型系统之外是不安全的
Scala by-name参数是一种语法糖,可以在需要延迟评估时使代码更具可读性.没有它,我们需要将"()=>"放在需要懒惰的所有内容之前.也就是说,虽然它在运行时只是一个函数0,但如果您可以将参数以外的任何内容定义为具有按名称类型,则在键入系统级别会出现问题.还要记住,FunctionN特性主要用于实现和Java互操作性,因为Java和JVM中没有函数类型.
明确
如果您确实需要明确输入,则以下内容将允许您具有限制性
def g(x: => Int) = x * x
val ggg: (=> Int) => Int = g _
更复杂的打字
按名称键入只能在函数类型声明的参数部分中使用.然后,函数类型本身可以在其他参数化类型中使用.
var funks: List[(=> Int) => Int] = Nil
funks ::= ggg
funks foreach { _ { println("hi"); 5 } }
| 归档时间: | 
 | 
| 查看次数: | 401 次 | 
| 最近记录: |