zoukankan      html  css  js  c++  java
  • scala def/val/lazy val区别以及call-by-name和call-by-value

    scala 学习

    参考链接:https://blog.csdn.net/qq_29343201/article/details/56281777

    scala def/val/lazy val区别以及call-by-name和call-by-value

    关于def/val/lazy val

    def

    def类似于每一次重新赋值,如果是用def定义函数,则是每一次重新获得一个函数

    val

    获得一次,并立即执行(严格执行)

    lazy val

    惰性执行,也就是赋值(绑定)的时候先不会执行,等到需要的时候再执行

    实验

    scala> def f = {println("hello"); 1.0}
    f: Double
    
    scala> f
    hello
    res3: Double = 1.0
    
    scala> f
    hello
    res4: Double = 1.0
    
    scala> f
    hello
    res5: Double = 1.0
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    这里使用的是def,则每一次获取一个新的,也就是每一次我使用f的时候,都会获得一个{ println(“hello”); 1.0},其值为1,但是中间过程会打印出hello,这是在赋值(绑定)的时候才会打印出来的,而使用def,则会每一次都打印出来

    scala> val f = { println("hello"); 1.0}
    hello
    f: Double = 1.0
    
    scala> f
    res6: Double = 1.0
    
    scala> f
    res7: Double = 1.0
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这里使用val,则只有一次绑定,所以后面不再打印出hello

    scala> lazy val f = { println("hello"); 1.0}
    f: Double = <lazy>
    
    scala> f
    hello
    res8: Double = 1.0
    
    scala> f
    res9: Double = 1.0
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这里使用的是lazy val,即为延迟执行的,可以看到在进行绑定的时候并没有打印出hello,也看不到其值,是因为现在还没有使用这个值,只是定义了这个值,在第二次进行使用的时候则会类似于val,第一次会打印出hello,之后就不再打印出了

    call-by-name和call-by-value

    scala的函数参数有两种情况,一种为by-value一种为by-name

    call-by-value

    默认情况的函数调用的参数为call-by-value, 
    比如:

    def callByValue(x: Int) = {
      println("x1=" + x)
      println("x2=" + x)
    }
    • 1
    • 2
    • 3
    • 4

    这种情况是默认的,也是显然的,就是call by value,翻译为按值传递,就是把具体的值传入x

    call-by-name

    按名传递,即将参数的“名字”传入,在不使用到的时候不提出他的值,类似于一种延迟执行 
    比如:

    def callByName(x: =>Int) = {
      println("x1=" + x)
      println("x2=" + x)
    }
    • 1
    • 2
    • 3
    • 4

    这样的写法就是call-by-name

    区别

    假设有一个函数,为func():

    def func() = {
    //这个函数有副作用,除了返回值还会打印出hello
      println("hello")
      1
    }
    • 1
    • 2
    • 3
    • 4
    • 5

    分别调用之前的两个函数:

    callByValue(func())
    这种情况,func会先执行,也就会先打印出hello一次,然后将返回的直接传入作为参数
    callByName(func())
    这种情况,func不会先执行,而是会整个代入(按名字传入)这个函数,在使用到的时候,也就是两次打印出x的时候再调用,这样就会出现两次hello了
    • 1
    • 2
    • 3
    • 4

    总结

    def 和 val的关系其实就是call-by-name和call-by-value的关系,def对应的是by-name,val对应的是by-value

     
  • 相关阅读:
    当你不知道今天星期几,不妨在编辑器写下这段代码
    自定义注解!绝对是程序员装逼的利器!!
    什么是可串行化MVCC
    Jetpack新成员,一篇文章带你玩转Hilt和依赖注入
    连接真机开发安卓(Android)移动app MUI框架 添加购物车等——混合式开发(四)
    从前世今生聊一聊,大厂为啥亲睐时序数据库
    工作五年,面试官说我只会CRUD!竟然只给我10K!
    bootstrap知识总结
    数据处理的两个基本问题05 零基础入门学习汇编语言42
    转移指令的原理02 零基础入门学习汇编语言44
  • 原文地址:https://www.cnblogs.com/txfsheng/p/9006872.html
Copyright © 2011-2022 走看看