对Scala感兴趣吗?参加DataCamp的Scala入门课程。
Scala是一种函数式编程语言,其中既包含作为一等值的函数和方法,也有相似之处和不同之处。函数和方法都是一段可重用的代码块,也用于将重复的代码存储在同一位置,调用函数执行特定的任务。它们还使代码更易于调试和修改。
然而,函数是一个初始化在变量中的对象,而方法以’def’关键词开头,后跟方法名、参数列表和带有返回值的方法体。
方法声明和定义
Scala中方法声明和定义的语法如下:
def 'method_name' ('parameters':'return_type_parameters') : ('return_type_of_method') = { 'method_body' return 'value' }
Scala中的方法从以下部分开始:
- ‘def’: 用于声明方法的关键词。
- ‘method_name’: 是你的方法名称,采用小驼峰命名法。
- ‘parameters’: 是方法参数,可以没有参数或只有一个参数,但当有多个参数时,参数之间用逗号分隔。
- ‘return_type_of_parameters’: 需要与’parameters_list’的数据类型匹配,并且是强制性的。
- ‘return_type_of_method’: 方法返回类型是可选的,但默认情况下返回’Unit’,可以使用’return’关键字返回值。
- 赋值符号(‘=’):是可选的,如果使用它将赋值返回值,不使用它则方法不返回任何内容。
- ‘method_body’:是大括号'{}’内的代码块,包含所需的逻辑或特定任务或操作。
- return:是用于返回所需值并终止程序的关键字,但在Scala中很少使用。
方法调用
Scala中方法调用的语法如下:
method_name(arguments)
方法调用可以通过’method_name’快速完成,这是要调用的对应方法的名称,附带传递参数。
带命名参数的方法
带命名参数的方法允许在方法调用时将参数传递给方法的参数,每个参数都会逐一与方法参数匹配。下面是一个带有函数声明和定义以及方法调用的示例:
object calculateResult { def funSub(x:Int, y:Int) : Int = { var diff:Int = 0 diff = x - y // return value return diff } def main(args: Array[String]) { // Function call println("Difference of the value is: " + funSub(8,6)); println("Difference of the value is " + funSub(y=6,x=8)); } }
上述程序的输出为:
值的差异为:2
值的差异为:2
以下程序包含一个名为 ‘calculateResult’ 的对象,其中包含一个名为 ‘funSub’ 的方法,该方法有两个参数 x 和 y,它们的返回类型为 ‘Int’,方法的总体返回类型也是 ‘Int’。随后是一个赋值语句,用于分配返回值。花括号表示方法体的开始,在这里变量 ‘diff’ 被初始化为0。主方法中的 ‘funSub(8,6)’ 方法调用将8匹配到 ‘x’,6匹配到 ‘y’,执行减法操作,并返回 ‘diff’ 的值,最终打印出来。同样,’funSub(x=8,y=6)’ 的方法调用中,参数的顺序无关紧要,6匹配到 ‘y’,8匹配到 ‘x’,进行类似的操作并返回结果输出。
默认参数值
您可以通过初始化相应的值来为方法参数指定默认值,并且在方法调用时不传递参数而留空。
object calculateResult { def funSub(x:Int=9, y:Int=6) : Int = { var diff:Int = 0 diff = x - y // return value return diff } def main(args: Array[String]) { // Function call print( "The final value is: " + funSub() ); } }
以上程序的输出为:
最终值为:3
上述程序包含一个定义为 ‘calculateResult’ 的对象,在该对象中有一个名为 ‘funSub’ 的方法,该方法带有参数 x 和 y,这两个参数的返回类型均为 ‘Int’,方法的总体返回类型也为 ‘Int’,后面跟着一个赋值语句,该赋值语句将返回值赋给变量。花括号表示方法体的开始,其中变量 ‘diff’ 被初始化为 0 的初始值。方法调用是从主方法内部进行的,其中 ‘funSub()’ 被调用并初始化 x 为 9 和 y 为 6,然后执行操作,使 ‘diff’ 的值被返回并打印出来。
可变参数
可变参数是接受任何变量数量参数的参数,可以由用户或客户端传递。方法中的最后一个参数使用 ‘*’ 声明,需要重复。
object variableArgument { def main(args: Array[String]) { printAll("Scala", "is", "great") } def printAll(strings: String*) { var i : Int = 0; for( value <- strings ){ println(value); i = i + 1; } } }
上述程序的输出为:
Scala
is
great
正如您所看到的,上述程序包含一个 ‘variableArgument’ 对象,其中有一个 ‘printAll’ 方法,该方法定义了一个可变参数 ‘String*’,在方法调用时可以传递一个字符串列表。传递的字符串列表在主函数内部被循环遍历,并作为输出显示。
递归函数
递归是函数式编程中使用的技术,其中问题通过反复将其分解为更小的子问题来解决,这些子问题与原始问题相似。解决越小的子问题,并将它们的解决方案应用于获得原始问题的解决方案。因此,它被称为分而治之或减而治之的问题,这使得代码变得简洁优雅。编写递归函数时,需要严格考虑两个要点:
- 基本情况:在需要找到否则可能导致无限递归的函数中可能有多个基本情况。它需要有一个解决方案,即不通过递归就能获得的简单形式的输出或解决方案。
- 递归情况:应用递归函数的情况,即正在进行递归调用。问题的关键在于,在每次递归调用中,需要减小大小,即问题需要分解为更小的子问题,直到达到基本情况。最后,您结合解决方案以得到主要问题,这称为分而治之的方法。
任何给定数字的阶乘是 n!,它可以用以下方式表示:
另外,您可以将项(n-1)。(n-2)…3.2.1表示为(n-1)!,所以任何给定数字的阶乘总是n。(n-1)!
现在您可以看到下面解决问题的递归方法。
object factorialDemo { def main(args: Array[String]) { for (i <- 1 to 5) println( "Factorial of " + i + ": = " + factorial(i) ) } def factorial(n: Int): Int = { if (n <= 1) return 1 else return n * factorial(n - 1) } }
上述程序的输出为:
1的阶乘:= 1
2的阶乘:= 2
3的阶乘:= 6
4的阶乘:= 24
5的阶乘:= 120
如您所见,在上面的程序中,有一个名为’factorialDemo’的对象,在其内部,有一个包含循环的’main’函数,该循环重复五次,并且还包括对’factorial’函数的调用,其中递归函数进行递归调用,即n到五次。当n小于或等于1时,它停止在基本情况下,并将结果返回并打印出来。
匿名函数
匿名函数是没有名称的轻量级函数定义,在Scala中被称为函数字面量。
匿名函数的语法和示例如下:
- 第一个语法和匿名函数的示例是:
语法:
('first_variable':'data_type', 'second_variable':'data_type') => "certain_expression"
示例:
(var1:String:var2:String) => var1 + var2
或者
- 第二个语法和匿名函数的示例是:
语法:
(_:'data_type')operator(_'data_type')
示例:
(_:String)+(_:String)
第一个语法显示,”=>”之后的表达式计算出一个特定的值,而”=>”之前的变量列表用于计算该表达式。
上述第二个语法像一个占位符,它只接受一次’通配符’字符的值,然后对这些值进行运算。
以下是一个匿名函数的示例:
object anonymousDemo { def main(args: Array[String]) { var function1 = (var1:Int, var2:Int) => var1 + var2 var function2 = (_:Int) + (_:Int) // function call println(function1(5, 5)) println(function2(7, 3)) } }
Initializing Scala interpreter ... Spark Web UI available at http://DESKTOP-03TH7J0:4040 SparkContext available as 'sc' (version = 2.4.3, master = local[*], app id = local-1566986265958) SparkSession available as 'spark' <console>:10: error: unbound placeholder parameter var function2 = {_:Int} + {_:Int} ^ <console>:10: error: unbound placeholder parameter var function2 = {_:Int} + {_:Int} ^
上述程序的输出如下:
10
10
如上所示,名为 ‘anonymousDemo’ 的对象包含 ‘main’ 函数和两个匿名函数。它们的语法不同,但可以产生相同的结果,’function’1 在被调用时从函数调用接收参数——传递值5和5,结果输出为10,而 ‘function2’ 也被调用,传递7和3,它一次接收值,接受任何有效的’Integer’进行加法运算并输出结果。
结论
恭喜,你已经完成了本教程的阅读。
Scala 中有许多高级主题,如高阶函数、嵌套函数、柯里化函数等。
参考资料:
Scala 基础概览
Scala | 函数 – 基础
Scala – 函数
Scala 中的匿名函数
查看 DataCamp 的 Scala 简介 课程。
Source:
https://www.datacamp.com/tutorial/basic-functions-methods-scala