Scala传名参数(By-Name)

1.=>

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

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

scala> List(1,2,3).map{(x: Int) => x*2}
res0: List[Int] = List(2, 4, 6)

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(1)
res0: String = my int: 1

scala> val test: Int => String = myInt => "my int: "+ myInt.toString
test: Int => String = <function1>

scala> test(1)
res1: String = my int: 1
  • 如果参数为空,即“=>”左边为空,形式是:() => 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")

7 > 9

}

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

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)

原文地址:https://www.cnblogs.com/duanxz/p/9567328.html

时间: 2024-08-29 17:04:16

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

scala的传名参数

scala如果你想实现像if ,while等类似的控制结构,根本没有值要传入花括号{}直接的代码里.要怎么实现. 比如说,我们要实现一个断言的控制结构,myAssert(), myAssert函数参考自带参数和一个标示变量,如果标示位为false,则什么都不做,如果为true则进行正常判断. 下面是一种合理的实现: val assertionEnable = true def myAssert( predicate: () => Boolean) = if(assertionEnable &

scala 基础四 scala 的函数扩展 默认参数,不定长参数,带名参数

默认参数,默认参数就是在函数定义的时候直接给函数的入参进行赋值 package smart.iot class func { } object func { //参数默认值 格式 参数:参数类型="要设置的默认值" def funcadd(str:String="hello scala!") { println(str); } def main(args: Array[String]): Unit = { funcadd() } } 输出:hello scala!

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

apply方法是Scala中十分常见的方法,你可以把这种用法当做是()操作符的重载形式. 像以上这样伴生对象的apply方法是Scala中构建对象的常用手法,不再需要使用new. if 条件表达式的值就是跟在if或else之后的表达式的值,如果两者类型不同,选择各分支类型的公共超类型作为返回类型. if(x>1) 1 相当于 if(x>1) 1 else () 你可以把()当做是表示"无有用值"的占位符,将Unit当做Java的Void 如果你在写较长的语句,需要分行来写的

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

项目中需要上传视频,图片等资源.最先做的是上传图片,开始在网上找了一款野鸡插件,可以实现图片上传预览(无需传到后台).但是最近这个插件出了莫名的问题,不易修复,一怒之下,还是决定找个大点的,靠谱的插件吧.加之上传视频就是用的webuploader,所以上传图片也理所当然选它了. 插件初始化,js引用什么的,官方文档上都写的比较清楚,建议直接去官方api去看 http://fex.baidu.com/webuploader/getting-started.html#图片上传 官方api上值给出了上

MyBatis查询传一个参数时报错:There is no getter for property named &#39;sleevetype&#39; in &#39;class java.lang.Integer

用MyBatis进行查询,传入参数只有一个时(非Map)如int,报错 There is no getter for property named 'sleevetype' in 'class java.lang.Integer 原因在于测试条件写法有误, <if test="sleevetype==0"><!-- 专属 --> exclusive=1 </if> <if test="sleevetype!=0">&l

jquery的uploadify插件多文件上传配置参数详解

最近做了个多文件上传,需要限制上传文件类型的例子.以前没做过找了一些资料,下次有用.同时也给大家做参考. uploader: uploadify.swf 文件的相对路径,该swf文件是一个带有文字BROWSE的按钮,点击后淡出打开文件对话框,默认值:uploadify.swf. script: 后台处理程序的相对路径 .默认值:uploadify.php checkScript:用来判断上传选择的文 件在服务器是否存在的后台处理程序的相对路径 fileDataName:设置一个名字,在服务器处理

Scala 深入浅出实战经典 第60讲:Scala中隐式参数实战详解以及在Spark中的应用源码解析

王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 腾讯微云:http://url.cn/TnGbdC 360云盘:http://yunpan.cn/cQ4c2UALDjSKy 访问密码 45e2土豆:http://www.tudou.com/programs/view/IVN4EuFlmKk/优酷:http://v.youku.com/v_show/id_

jsp页面间传中文参数示例(页面传参数编码)

在url地址栏使用中文传参数可能会是乱码了,下面我们来看看正确的jsp中页面间传中文参数转码的方法. 转码代码: String tcontent = "测试":a.href="./showCont.jsp?tcontent="+encodeURI(encodeURI(tcontent)); 解码代码: java.net.URLDecoder.decode((String)request.getParameter("tcontent"), &quo

C# ContentType: &quot;application/json&quot; 请求方式传json参数问题

处理Http请求时遇到的ContentType为application/json方式,记录下这种Post请求方式下如何传json参数: var request = (HttpWebRequest)WebRequest.Create("http://url"); request.ContentType = "application/json"; request.Method = "POST"; using (var streamWriter = n