Scala 函数

闭包

  • 如下 addMore 成为一个“闭包”。因为它引用到函数外面定义的变量。定义这个函数的过程,是将和这个自由变量捕获二构成一个封闭的函数。
scala> var more =1
more: Int = 1

scala> val addMore = (x:Int) => x + more
addMore: Int => Int = <function1>

scala> addMore (100)
res1: Int = 101

scala> more =  9999
more: Int = 9999

scala> addMore ( 10)
res2: Int = 10009

可变参数

  • Scala中使用 * 来知名该参数为重复参数
scala> def echo (args: Any *) =
     |   for (arg <- args) println(arg)
echo: (args: Any*)Unit

scala> val arr = Array("java","scala","python")
arr: Array[String] = Array(java,scala,python)

scala> echo ("Hello",123,true,arr)
Hello
123
true
[Ljava.lang.String;@2c282004
  • 若要只传入数组的值,可用以下方法
scala> echo(arr: _*)

命名参数

  • 顾名思义 就是在调用函数时,参数传入和函数定义刘表是一一对应,允许使用任意顺序。如下:
scala> def add(one: Double, two: Double) :Double = one + tow
add: (one: Double, two: Double) Double

scala> add(two=10, one=2)
res1: Double = 12.0

高阶函数

  • 函数的参数也可以是另一个函数
  val arr = Array("javaisgood", "thisscala", " 123456")

  def strMatcher(matcher: (String) => Boolean) = {
    for(str <- arr; if matcher(str))
      yield str
  }

  def strEnding(str: String) = strMatcher(_.endsWith(str))

  def strContaining(str: String) = strMatcher(_.contains(str))

  def strRegex(str: String) = strMatcher(_.matches(str))

柯里化函数

  • 柯里化是把接收多个参数变换成接收一个单一参数(最初函数的第一个参数)的函数,返回接收余下的参数而且返回结果的新函数的技术。
  // common function
  def add(x: Int, y: Int) = {
    println("x: " + x)
    println("y: " + y)
    x + y
  }

  //curry function
  def _add(x: Int)(y:Int) = {
    println("_x: " + x)
    println("_y: " + y)
    x + y
  }

  // split
  def first(x: Int) = (y: Int) => {
    println("__x: " + x)
    println("__y: " + y)
    x + y
  }
first: (x: Int)Int => Int
scala> val second=first(1)
second: Int => Int = <function1>

scala> second(2)
res1: Int = 3

scala> val onePlus = _add(1)_
onePlus: Int => Int = <function1>

  • 其中 _ 作为第二参数列表的占位符

Call By Name & Call By Value

Call by value(传值调用)
使用 (变量 :类型)
Call by name(传名调用)
使用 (变量 : => 类型)
注意 ":" 和 "=>"之间一定要有空格

  def main(args: Array[String]) {
    // testOne
    testCallByNameAndValue(1,testLoop(6))
    // testTwo
    testCallByNameAndValue(testLoop(6),1)
  }
  // x为传值调用,y为传名调用
  def testCallByNameAndValue(x: Int,y: => Int) = {
    println("scala")
    1
  }
  def testLoop(a: Int):Int = {
    for (i <- (0 until a)) println("Iteration" + i)
    1
  }
// results of execution
// testOne
scala
// testTwo
Iteration0
Iteration1
Iteration2
Iteration3
Iteration4
Iteration5
scala

总结:

Call By Value :无论方法是否使用该参数都要先将该参数的值计算出来再传入
Call By Name :只有在该参数被方法使用时才计算该参数的值

定义新的的控制结构

scala> def twice (op:Double => Double, x:Double) =op(op(x))
twice: (op: Double => Double, x: Double)Double

scala> twice(_ + 1, 5)
res0: Double = 7.0

  • 在Scala中,如果调用的函数只有一个参数,可以使用 {} 来代替 ()
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 文 /巴隐人 文有一个小孩儿撒娇成性,在疯狂地打闹其父亲。其妈说:“你把爸爸打死了,你就没有爸爸...
    巴隐人阅读 2,312评论 0 1
  • 知识很多,就像茫茫无边的大海,只有坚持不懈,不断获取知识,才会成为有学问的人。光阴似箭,日月如梭。当停下脚...
    广南县126严孟艳阅读 4,748评论 3 1
  • 我找到了一个小岛,四季如春,并不只是气候。那时候啊,它像是个理想国。 后来我有了上岛的机会,可是同行的人太多,我无...
    JOYL阅读 1,724评论 0 0
  • 愿你接受身上所有的特质 既不构成自负 也不构成自卑 就那么从容、恬淡 愿你与他人始终平和相待 不至于过分热情 也不...
    秋风误阅读 1,630评论 0 3
  • 文/任俊杰 如果从1956年一路追随巴菲特,一定会惊呆于财富回报。但在计算时需要采取两种口径: 按伯克希尔每股净值...
    谢宇衡阅读 2,849评论 1 2

友情链接更多精彩内容