这是一个定义并尝试一些功能的 Scala 小 session :
scala> def test1(str: String) = str + str;
test1: (str: String)java.lang.String
scala> test1("ab")
res0: java.lang.String = abab
效果很好。
scala> val test2 = test1
<console>:6: error: missing arguments for method test1 in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
val test2 = test1
^
糟糕。
scala> val test2 = test1 _
test2: (String) => java.lang.String = <function1>
scala> test2("ab")
res1: java.lang.String = abab
效果很好!
现在,我已经看到了折叠时的 _
语法(_ + _
等)。据我了解, _
基本上意味着“一个论点”。所以 test1 _
基本上意味着一个带有参数的函数,该函数被赋予 test1
”。但是为什么这不完全与刚才的相同test1
?为什么我附加一个_
会有不同?
所以我不断探索...
scala> val test3 = (str: String) => str + str
test3: (String) => java.lang.String = <function1>
scala> test3("ab")
res2: java.lang.String = abab
scala> val test4 = test3
test4: (String) => java.lang.String = <function1>
这里无需 _
即可运行! def
ed 函数和 val
ed 函数有什么区别?
最佳答案
def
在周围的对象/类/特征中声明一个方法,类似于在 Java 中定义方法的方式。您只能在其他对象/类/特征中使用 def
。在 REPL 中,您看不到周围的对象,因为它是“隐藏的”,但它确实存在。
您不能将 def
分配给值,因为 def
不是一个值 - 它是对象中的一个方法。
(x: T) => x * x
声明并实例化一个在运行时存在的函数对象。函数对象是扩展 FunctionN
特征的匿名类的实例。 FunctionN
特征带有一个 apply
方法。名称 apply
很特殊,因为它可以省略。表达式 f(x)
被脱糖为 f.apply(x)
。
底线是 - 由于函数对象是存在于堆上的运行时值,因此您可以将它们分配给值、变量和参数,或者从方法中将它们作为返回值返回。
为了解决将方法分配给值的问题(这可能很有用),Scala 允许您使用占位符从方法创建函数对象。上面示例中的表达式 test1 _
实际上在方法 test1
周围创建了一个包装函数 - 它相当于 x => test1(x)
。
关于function - 在 Scala 中定义函数的两种方法。有什么不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5009411/