为什么在Scala中使用def和val,或者反之亦然?

14 浏览
0 Comments

为什么在Scala中使用def和val,或者反之亦然?

我知道这个问题在SO的其他帖子中已经讨论过了,并且我理解了defval的基本区别。 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可互换地声明和初始化一个变量吗?

0
0 Comments

在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定义的变量是在创建时计算的,并且在后续的调用中保持不变。具体使用哪种方式取决于具体的需求和性能考虑。

0
0 Comments

在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

从上面的例子中可以看出,方法和值的一个重要区别在于求值的时机。方法在每次调用时都会重新求值,而值只在初始化时求值一次。

关于defvalvar之间的区别,可以参考这个回答:stackoverflow.com/questions/4437373/…

0
0 Comments

为什么在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(...)(...)(...)始终有三个参数列表。它们只可能为空。”)

0