scala中.map(…)和.map {…}之间的区别是什么
我是斯卡拉的新手.高阶函数跟随括号或括号块之间是否有任何差异?
例如: >列表(1,2,3).map(i => i 1) 它们都得到相同的结果:List(2,3,4) 但是对于这个例子List(1,2).map {println(“Hi”); _ 1}结果如下,为什么’Hi’只打印一次? Hi List[Int] = List(2,3) 解决方法
Scala中的一个块只是一个表达式.与括号一样,它们对于将代码组合在一起非常有用.与括号不同,块不包含一个表达式,但可以包含一个或多个表达式.块的值是其中最后一个表达式的值.
{println(“嗨”); _ 1}相当于{println(“Hi”); (i:Int)=>我1}.这是一个打印出“Hi”的块,它的值是一个添加一个的函数.在执行退出块之前打印字符串,它生成的函数对println一无所知. 以下是这些规则的一些示例: list.map(i => i + 1) // ^----------^ // function literal passed as argument list.map(_ + 1) // ^---^ // Underscore shorthand for above list.map({ i => i + 1 }) // Identical to above. // The block only contains one expression,so it has the value of that expression // Otherwise stated: { expr } === expr list.map({ println("Hi"); _ + 1 }) // ^-----2-----^ ^-3-^ // ^------------1---------^ // 1: The argument to map is the value of this block // 2: The first statement of the block prints something. This is only executed once,// because it's not the *block* being passed as argument,it's its value. // 3: Function literal in underscore notation. This is the value of the block // and this is what map sees. // Order of operations (approx. bytecode): // load list onto stack // load string "Hi" onto stack // call println and pop string off stack // create function (i => i + 1) on top of stack // invoke map with argument (i => i + 1),popping list and function off stack list.map { println("Hi"); _ + 1 } // Identical to above,but Scala lets you omit the () because you are using {} list.map({ i => println("Hi"); i + 1 }) // Function literals grow as big as they can be. // The block contains only one expression,which is (i => println("Hi"); i + 1) // This function prints "Hi" and then returns i + 1 // This call to map will print "Hi" for every element list.map { i => println("Hi"); i + 1 } // Identical to above,but Scala lets you omit the () because you are using {} 此外,还有要处理的名称参数.按名称参数声明如下: def func(a: => String) // Not () => String,it's => String 当你有by-name参数时,那么 func { println("x"); _ + 1 } 实际上将整个块作为参数传递.该块仍然评估为i => i 1,但是func控制了评估何时发生.具体来说,块的代码被转换为Function0并传递给func,func可以根据需要多次调用它,并带有副作用.这可以用来产生很好的效果,基本上允许普通函数像自定义控制流操作符一样工作: @tailrec def repeat(i: Int)(op: => Any): Unit = if(i == 0) () else { require(i >= 0,s"negative repeat amount: $i") op // Evaluate op repeat(i - 1)(op) // Won't evaluate op; will let sub-call deal with it } repeat(5) { println("Hi"); println("Bye") } // Hi // Bye // Hi // Bye // Hi // Bye // Hi // Bye // Hi // Bye 注意如何在块周围省略括号,这实际上使得它看起来像定义控制流操作符的能力. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |