function - 在 Scala 中定义函数的两种方法。有什么不同?

标签 function scala currying

这是一个定义并尝试一些功能的 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>

这里无需 _ 即可运行! defed 函数和 valed 函数有什么区别?

最佳答案

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/

相关文章:

sql-server - sql server 2012 - 无法对多语句表值函数的选择授予

scala - 使用 slick 插入后返回自动递增值

haskell - 组合函数组合 : How does (. ).(.) 有效吗?

c++ - 指针函数

c# - 函数不返回反转数组

function - 在 PowerShell 控制台中恢复到原始提示

scala - scala 构造函数参数默认为 private val 吗?

scala - 使用 Specs2 测试 Akka

scala - 无法应用参数化柯里化(Currying)函数

typescript - 柯里化(Currying)函数的返回类型