为什么在Scala中使用def和val,或者反之亦然?
为什么在Scala中使用def和val,或者反之亦然?
我知道这个问题在SO的其他帖子中已经讨论过了,并且我理解了def
和val
的基本区别。 def
用于定义一个方法,val
用于定义一个不可变引用。我提出这个问题的目的是想了解def
是否还有其他用途,它能否与val
互换使用?\n最近我尝试了下面的代码,但无法确信我对def
的理解是否足够:\n
scala> def i: Int = 3 i: Int scala> i res2: Int = 3
\n所以我很好奇,这是否等同于val i = 3
?\n然后我尝试了这个:\n
scala> i():9: error: Int does not take parameters i()
\n我这样做只是为了测试我对def
语义的理解。现在我想知道,当i
是一个方法时,为什么Scala会报错“...不接受参数”?\n接下来我尝试了下面的代码:\n
scala> def i(): Int = 3 i: ()Int scala> i() res4: Int = 3
\n这次Scala似乎认同i
是一个方法。那么我可以将def
用作val
可互换地声明和初始化一个变量吗?
在Scala中,可以使用def和val来定义方法和变量。那么为什么要在Scala中使用def或val,或者二者之间的区别是什么呢?
在上面的例子中,我们可以看到通过使用val来重写trait中的def。在trait A中,我们定义了两个抽象方法i和num。然后在类B中,我们使用val关键字来实现了这两个方法。在创建B的实例b后,我们可以通过调用b.i和b.num来访问这两个值。
为什么要使用def和val之间的区别呢?这是因为它们在Scala中具有不同的语义。使用def定义的方法是每次调用时都会重新计算的,而使用val定义的变量是在创建时计算的,并且在后续的调用中保持不变。
这种区别在性能方面是非常重要的。如果一个方法的结果在每次调用时都会发生变化,那么使用def来定义它可能更合适,因为它可以确保每次调用时都会重新计算结果。另一方面,如果一个值在创建时就已经确定,并且在后续的调用中不会发生变化,那么使用val来定义它可能更有效率,因为它只需要计算一次。
当然,这只是使用def和val的一种常见用法,具体的使用方式还取决于具体的需求和设计。有时候可能需要在方法内部使用val来定义临时变量,或者在方法之间共享状态时使用def。在实际使用中,需要根据具体情况来判断使用哪种方式。
总结起来,使用def和val的区别在于方法和变量的计算时机和是否可变。使用def定义的方法是每次调用时都会重新计算的,而使用val定义的变量是在创建时计算的,并且在后续的调用中保持不变。具体使用哪种方式取决于具体的需求和性能考虑。
在Scala中,我们可以使用def
关键字定义一个方法,使用val
关键字定义一个不可变的值。这两种方式的一个主要区别在于=
右侧的表达式何时被求值。对于一个方法而言,在每次调用方法时都会对表达式进行求值;而对于一个值而言,在初始化值时对表达式进行求值。
例如,考虑下面的代码段:
def i: Int = { println("Hello"); 3 } i i
使用def
定义的方法i,在每次调用时都会打印出"Hello"并返回值3。所以输出结果为:
Hello res0: Int = 3 Hello res1: Int = 3
而如果我们使用val
定义一个值i,则在初始化时就会对表达式进行求值。所以输出结果为:
Hello res2: Int = 3
从上面的例子中可以看出,方法和值的一个重要区别在于求值的时机。方法在每次调用时都会重新求值,而值只在初始化时求值一次。
关于def
、val
和var
之间的区别,可以参考这个回答:stackoverflow.com/questions/4437373/…
为什么在Scala中要使用def和val,或者反过来?这个问题的出现是因为在声明方法时,可以使用两种方式:一种是没有参数列表的方法,另一种是带有空参数列表的方法。前者通常用于没有副作用的方法,而后者用于有副作用的方法。
如果一个值从不改变并且您想避免重新计算它,应该使用val而不是def。每次调用def时都会重新计算它,而val只在分配值时计算一次。
只是为了重申一下,对于不带参数的任何方法,您可以使用括号或不使用括号,使用括号表示具有副作用的方法仅仅是一种约定,但我强烈建议您遵守它。但是,如果您像这样做def dontDoThis = println("Hi!")
编译器不会阻止您。
这些都是正确的答案。所以按照这个逻辑,我可以说val list = List(1,2,3),然后我可以调用list.size()或list.length()。两者都是没有副作用的方法,对吗?所以我也可以这样调用它们:list.size或list.length。
您可以调用使用()
声明的方法时可以省略括号,但是不能调用没有括号声明的方法时添加括号。
我明白了。微妙而且有道理。
只是作为参考:您可以定义带有任意数量的空参数列表的方法:def i()()() = 3
。
这很有趣。有没有一个使用任意数量的空参数列表的方法的用例呢?
那么你只能部分应用函数。对于没有参数的情况并没有意义。
它也可能用于机器生成的代码,这样您就可以避免特殊情况。(“这个生成的方法被称为someMethod(...)(...)(...)始终有三个参数列表。它们只可能为空。”)