我知道使用def / val在scala中定义函数之间的基本区别:如果我使用val,我的函数定义一次,如
scala> val valRandom = Random.nextInt
valRandom: Int = 2032538454
scala> valRandom
res0: Int = 2032538454
但我的问题是为什么每次使用像:
这样的函数时都会计算Random.nextIntscala> val valRandom2 = (_:Int) + Random.nextInt
valRandom2: Int => Int = $$Lambda$1100/1597979904@1a6dc5ea
scala> valRandom2(0)
res2: Int = 486047489
scala> valRandom2(0)
res3: Int = 1573520480
答案 0 :(得分:2)
在你的第一种方法中,
scala> val valRandom = Random.nextInt
valRandom: Int = 2032538454
如果您发现valRandom
的类型为int
。基本上,您已使用Random.nextInt
初始化valRandom。
但是,在第二种方法中,
scala> val valRandom2 = (_:Int) + Random.nextInt
valRandom2: Int => Int = $$Lambda$1100/1597979904@1a6dc5ea
您注意到valRandom2
的类型是Int -> Int
的映射
valRandom2是一个函数值,它只是一个匿名函数或一个lambda表达式。
因此,每当您调用它时,它始终会生成新值。
两种方法的不同之处在于第一种方法是创建变量并为其分配随机值。但是在第二种方法中,您正在调用匿名函数,因此每次都会进行评估
答案 1 :(得分:0)
在valRandom2中,随机偏移量在函数体内计算,因此每次调用函数时都会计算它。
您需要计算函数外部的随机偏移量,如下所示:
val valRandom3 = { val rand = Random.nextInt; (_:Int) + rand }
答案 2 :(得分:0)
我的回复:
scala> val valRandom2 = (_:Int) + Random.nextInt
valRandom2: Int => Int = <function1>
所以valRandom2是一个东西,它接受一个Int并返回一个Int,并且类型为function1。例如:
scala> val valRandom3 = (_:Int) + (_:Int) + Random.nextInt
valRandom3: (Int, Int) => Int = <function2>
这是function2类型。
数字(1,2)表示传入了多少参数。函数总是返回一个值,所以这并不重要。即使没有返回,因为它是一个过程,可能需要副作用,它会隐式返回Unit()。如果它返回一个东西或一个元组的List,这只是一件事,你必须分开,以获得多个值中的一个。
功能与方法无关。函数可以传递并且执行被延迟,而方法是直接调用的,但是将方法作为函数传递很容易。
scala> def add (a: Int, b:Int) : Int = a + b
add: (a: Int, b: Int)Int
scala> def mul (a: Int, b:Int) : Int = a * b
mul: (a: Int, b: Int)Int
scala> def printIt (a: Int, b:Int, f:(Int, Int) => Int) = {
| val c = f (b, a)
| println (s"b $b (X) a $a = c $c")
| }
printIt: (a: Int, b: Int, f: (Int, Int) => Int)Unit
scala> printIt (3, 4, add)
b 4 (X) a 3 = c 7
scala> printIt (3, 4, mul)
b 4 (X) a 3 = c 12
这个例子虽然简单易懂,但并没有解释为什么它有用,但有用的例子设置起来比较复杂。但想象一下可以对数值进行排序的List。如果你有一个Employees列表,你可以通过将一个函数交给List来对它们进行排序,从Employee中获取一个Numeric,可以是Employee.id,* .age,* .maxSalary(),. add.zipCode或者无论如何,这会给你最大的灵活性。
评论:
scala> val valRandom2 = {println ("vR2 called"); (_:Int) + Random.nextInt}
vR2 called
valRandom2: Int => Int = <function1>
scala> val x = valRandom2 (0)
x: Int = -1231081
scala> val x = valRandom2 (0)
x: Int = 1421497830
为什么在声明时执行打印,但在使用时执行nextInt?
因为
scala> val valRandom2 = {println ("vR2 called"); (_:Int) + Random.nextInt}
vR2 called
valRandom2: Int => Int = <function1>
scala> val valRandom2 = {println ("vR2 called"); (_:Int) + Random.nextInt}
vR2 called
valRandom2: Int => Int = <function1>
scala> val x = valRandom2
x: Int => Int = <function1>
rhs的结果是函数,它被赋值给valRandom2或x,而print是声明的副作用。该块作为其最后一个表达式返回该函数。
在valRandom2上交换内部调用,你什么也得不到(单位)。
将参数Int添加到第二个调用:
scala> val valRandom3 = {Random.nextInt; (_:Int) => println ("vR2 called") }
valRandom3: Int => Unit = <function1>
scala> valRandom3 (0)
vR2 called
scala> valRandom3 (0)
vR2 called