Scala 什么是;代码:=>;单位「;在斯卡拉是什么意思?
有人知道scala中=>单元的类型吗?我不知道=>Unit的含义以及如何使用它。我定义了一个函数,如下所示:Scala 什么是;代码:=>;单位「;在斯卡拉是什么意思?,scala,types,Scala,Types,有人知道scala中=>单元的类型吗?我不知道=>Unit的含义以及如何使用它。我定义了一个函数,如下所示: def test(code: => Unit){ print("start ...") code print("end ....") } test(print(1)) 它是否意味着一个有任何参数返回单位的函数 感谢在x:=>中键入x是一个按名称调用参数。这不同于接受一个不接受任何参数的函数的参数:x:()=>Type这种参数是按名称参数调用的 =>B表示返回B
def test(code: => Unit){
print("start ...")
code
print("end ....")
}
test(print(1))
它是否意味着一个有任何参数返回单位的函数
感谢在
x:=>中键入x
是一个按名称调用参数。这不同于接受一个不接受任何参数的函数的参数:x:()=>Type
这种参数是按名称参数调用的
=>B
表示返回B
值的代码块a,其目的是仅在调用参数时对其求值
def foo(code: => Int) {
println("Not yet evaluated")
val result = code
println("parameter evaluated %s, is it an int ? %s " format (
result, result.isInstanceOf[Int]) )
}
您可以通过以下方式调用foo
:
foo(1)
或
传递参数的另一种方式是按值:在将参数发送到方法之前对其进行求值
def foo(code : Int) {
println("Parameter already evaluated")
val result = code
println("parameter evaluated : " + result)
}
工具书类
它表示按名称调用,这基本上意味着在函数中使用时计算值。与Java(以及使用常规类型语法的Scala)中默认的按值调用相反,在Java中,值是在调用方法之前计算的。我想,单位类型在按值调用中没有多大意义
这通常用于创建作为自定义控件结构的函数,或者像示例中的计时或日志记录之类的东西。在Java中经常使用AOP执行的操作。这称为参数,与按名称调用参数评估策略相关。有关传递参数的类似但不完全相同的方法,请参阅链接的wikipedia文章
为了更好地解释它,让我们首先考虑两种最常用的参数评估策略:按值调用和引用调用。
按值调用是迄今为止最常见的评估策略。例如,它是java中唯一的策略,而C中的默认策略考虑,例如,这个简单的java程序:
public class ByValue {
static public void inc(int y) {
y++;
}
static public void main(String... args) {
int x = 0;
inc(x);
System.out.println(x);
}
}
它将打印0
,因为x
的值被复制到y
,因此当y
增加时,它不会更改x
中的原始值。将此与C++程序进行对比,引用如下:< /P>
#include <stdio.h>
void inc(int &y) {
y++;
}
int main() {
int x = 0;
inc(x);
printf("%d\n", x);
}
本例打印的是2
,而不是1
,因为作为参数传递的代码块被求值两次。执行时,就好像main
中的第二行是这样写的:
x = if ({ val tmp = x; x += 1; tmp }) { val tmp = x; x += 1; tmp } + 1 else { val tmp = x; x += 1; tmp }
现在,按名称参数至少有三个有趣的用途:
它可以用来延迟某件事情的执行直到合适的时间
在某些情况下,它可以用来避免执行
它可以用来多次执行某些代码块
我认为,第一个和最后一个案例非常明显。下面是第二种情况的一个示例:
implicit def fromBoolean(b: Boolean) = new {
def and(that: => Boolean): Boolean = if (b) that else b }
val x = 0
(x > 0) and (10 / x > 0)
如果该
不是按名称参数,则会在最后一行引发异常。实际上,它只会返回false
,具体来说,这是不同的,因为在调用站点,要计算的表达式是直接给出的,而不是作为函数给出的(因此test(print(1))
而不是test(()=>print(1))
)。感谢关于“函数不带参数”的部分当前位置我正在寻找有关该语法的解释。当然,这是完全有意义的,所以我应该自己弄清楚:)关于调用示例,在传入多行代码块时,在参数周围放上括号更为惯用:foo{…}
。这不是一个好答案,因为它没有区分按名称参数和惰性(按需调用)参数参数。@Dianel您能帮我说明一下如何增强我的答案吗?例如,一种情况可以明确区分这两种情况@亚伦edited@ashy_32bit大概我认为人们往往会误解名称参数,将其与函数混淆,然后绊倒在事实上,因为它们不是痛苦的方式。@DanielC Sobral:令人敬畏的深度回答。它甚至比“Scala中的函数编程原理”课程中的更好。也许值得建立一个包含在线REPL的页面,让人们“试验”代码,更具体地“体验”差异。测试中的一个解释足够抽象,这个概念很难理解,特别是如果一个人已经广泛使用Java很多年了。
x = if ({ val tmp = x; x += 1; tmp }) { val tmp = x; x += 1; tmp } + 1 else { val tmp = x; x += 1; tmp }
implicit def fromBoolean(b: Boolean) = new {
def and(that: => Boolean): Boolean = if (b) that else b }
val x = 0
(x > 0) and (10 / x > 0)