1.=>

在了解Scala的By-Name参数之前,先了解下“=>”在Scala中有几种用法:

1.对于值,“=>”相当于lambda表达式。如:

scala> List(,,).map{(x: Int) => x*}
res0: List[Int] = List(, , )
2.对于类型,“=>”两端的类型(如,A => B、(A, B) => C等)。它对于Function<n>[A[, B...], T]是一个语法糖。一个函数传入参数是A[, B...],并且返回一个T类型的值。如:

scala> val test: Function1[Int,String] = myInt => "my int: " + myInt.toString
test: Int => String = <function1>
scala> test()
res0: String = my int: scala> val test: Int => String = myInt => "my int: "+ myInt.toString
test: Int => String = <function1> scala> test()
res1: String = my int:
  • 如果参数为空,即“=>”左边为空,形式是:() => T。如

    scala> val test: Function0[String] = () => "Hello"
    test: () => String = <function0> scala> test()
    res3: String = Hello scala> val test: () => String = () => "Hello"
    test: () => String = <function0> scala> test()
    res4: String = Hello

如果无返回值,即“=>”右边为空,形式是:A[, B...] => Unit

    1. scala> val test: Int => Unit = myInt => println(myInt)
    2. test: Int => Unit = <function1>
    3. scala> test(1)
    4. 1
  • 如果无参且无返回值,即“=>”两边都为空,形式是:() => Unit
    1. scala> val test: Function0[Unit] = () => println("Hello")
    2. test: () => Unit = <function0>
    3. scala> test()
    4. Hello
    5. scala> val test: () => Unit = () => println("Hello")
    6. test: () => Unit = <function0>
    7. scala> test()
    8. Hello

3.如果作为一个函数的参数的类型声明,且左边没有任何符号,如def func(param: => T)。这种形式叫做By-Name parameter。

4.在case语句中,“=>”用于分隔模式和结果表达式。

 

2.By-Name Parameter

By-Value参数,我们都比较熟悉,参数在进入函数前就进行计算,最后传入的最终的计算结果。
By-Name参数,表示参数在进入函数后,每次在函数体内调用的时候才会计算。

def myByName1(param: () => Boolean): Unit = {

println("start")

println(param) //println(param.apply())也可以

println("end")

}

//要实现传名函数,要定义的类型开始于“=>”,而不是“() =>”。

//myByName1{7>9}不会有效,因为缺少“() =>”

myByName1{() =>

println("enter")

 > 

}

其中“=>”后面的代码是整体作为参数,所以会在函数体里被调用的时候才会执行。输出如下:

start

enter

false

end

再看下一种情况,只有“() =>”之后的代码是By-Name参数。“() =>”之前的代码是By-Value参数,即当调用myByName2的时候就会立即执行:

  1.  
    def myByName2(param: () => Boolean): Unit = {
  2.  
    println("start")
  3.  
    println(param) //println(param.apply())也可以
  4.  
    println("end")
  5.  
    }
  6.  
     
  7.  
    myByName2{
  8.  
    println("enter")
  9.  
    () => 7 > 9
  10.  
    }

输出如下:

  1.  
    enter
  2.  
    start
  3.  
    false
  4.  
    end

下面来看标准的By-Name参数: 

  1.  
    def myByName(param: => Boolean): Unit = {
  2.  
    println("start")
  3.  
    println(param)
  4.  
    println("end")
  5.  
    }
  6.  
     
  7.  
    myByName{
  8.  
    println("enter")
  9.  
    7 > 9}

3.函数作为参数

By-Name有点像把函数作为参数的意思,但是实际上却不是。这里看下把函数作为参数的形式:
    1.  
      def test(num: Int => String, str: String => Int): Unit = {
    2.  
      val i = 10
    3.  
      val s = "5"
    4.  
      println(num(i))
    5.  
      println(str(s))
    6.  
      }
    7.  
       
    8.  
      def num(x: Int): String = {
    9.  
      x.toString()
    10.  
      }
    11.  
       
    12.  
      def str(s: String): Int = {
    13.  
      s.toInt
    14.  
      }
    15.  
       
    16.  
      test(num, str)

Scala传名参数(By-Name)的更多相关文章

  1. scala -- 传名参数

    object Test{ def main(args: Array[String]): Unit = { def test(code : => Unit){// 传名参数 不计算函数值,而是把函 ...

  2. scala的传名参数

    scala如果你想实现像if ,while等类似的控制结构,根本没有值要传入花括号{}直接的代码里.要怎么实现. 比如说,我们要实现一个断言的控制结构,myAssert(), myAssert函数参考 ...

  3. 快学Scala 第二课 (apply, if表达式,循环,函数的带名参数,可变长参数,异常)

    apply方法是Scala中十分常见的方法,你可以把这种用法当做是()操作符的重载形式. 像以上这样伴生对象的apply方法是Scala中构建对象的常用手法,不再需要使用new. if 条件表达式的值 ...

  4. Scala 函数入门之默认参数和带名参数

    Scala 默认参数 在Scala中,有时我们调用某些函数时,不希望给出参数的具体值,而希望使用参数自身默认的值,此时就定义在定义函数时使用默认参数. def sayHello(firstName: ...

  5. 百度上传工具webuploader,图片上传附加参数

    项目中需要上传视频,图片等资源.最先做的是上传图片,开始在网上找了一款野鸡插件,可以实现图片上传预览(无需传到后台).但是最近这个插件出了莫名的问题,不易修复,一怒之下,还是决定找个大点的,靠谱的插件 ...

  6. ajaxFileUpload上传带参数,返回值改成json格式

    /*直接复制在自己的js文件中就能使用*/ jQuery.extend({ createUploadIframe: function (id, uri) { //create frame var fr ...

  7. springboot 传List参数

    最近项目有个需求,前台需要传list参数请求controller接口,一开始直接使用ResponseBody注解,但实践下来发现参数没有传到controller. 现将处理方式记录如下:  1.前台 ...

  8. javascript之url转义escape()、encodeURI()和decodeURI(),ifram父子传参参数有中文时出现乱码

    ifram父子传参参数有中文时出现乱码,可先在父级页面用encodeURI转义,在到子页面用进行decodeURI()解码 我们可以知道:escape()除了 ASCII 字母.数字和特定的符号外,对 ...

  9. javaWeb传收参数方式总结

    有时候,我真会被传参搞得头晕,这样传要怎么接收,那样传又要怎么接收? get可以json吗?什么是json方式提交?等等问题,已困扰我许久 所以,在此想做个总结,整理一下思绪,不再为传收参烦恼!如有错 ...

随机推荐

  1. Java异常处理的方法

    1.异常概述在程序中,错误可能产生于程序员没有预料到的各种情况,或者是超出了程序员可控制范围的环境因素,如用户的坏数据.试图打开一个根本不存在的文件等.在Java中这种在程序运行是可能出现的一些错误称 ...

  2. Hive错误:Error: FUNCTION 'NUCLEUS_ASCII' already exists. (state=X0Y68,code=30000)

    问题 初始化derby失败: [root@bigdata111 apache-hive-2.3.0-bin]# schematool -dbType derby -initSchemaSLF4J: C ...

  3. java-Date类

    1.Date类的概述和方法使用 * A:Date类的概述 * 类 Date 表示特定的瞬间,精确到毫秒. * B:构造方法 * public Date() * public Date(long dat ...

  4. EasyUI datagrid 格式 二

    单击保存,改表的状态 { field: 'ck', checkbox: true }, $("tr").each(function () { if ($(this).find(&q ...

  5. 20165313Java实验四 Android程序设计

    实验报告封面 课程:Java程序设计 班级:1653班 姓名:张晨晖 学号:20165313 指导教师:娄嘉鹏 实验日期:2018年5月14日 实验时间:13:45 - 15:25 实验序号:实验四 ...

  6. java中类加载时机

    java虚拟机规范虽然没有强制性约束在什么时候开始类加载过程,但是对于类的初始化,虚拟机规范则严格规定了有且只有四种情况必须立即对类进行初始化,遇到new.getStatic.putStatic或in ...

  7. mysql 之mvcc多版本控制

    MVCC是multiversion concurrency control的缩写,提供MySQL事物隔离级别下无锁读,例如一个事物在执行update等修改数据的sql,并未提交时其他事物进行数据读取是 ...

  8. 二分法求常数E,常数π,根号2

    进行单元测试数据____________________________________ public class Test { public static void main(String[] ar ...

  9. doubleclick adx note

    1, cid . is billing_id from  Main.html#PRETARGETING otherwise creative id will not upload to  creati ...

  10. out, ref 和 params 的区别和用法

    1. out 参数. 如果你在一个方法中,返回多个相同类型的值,可以考虑返回一个数组. 但是,如果返回多个不同类型的值,返回数组就不可取.这个时候可以考虑使用out参数. out参数就侧重于在一个方法 ...