gpt4 book ai didi

scala - Scala for 推导式中 val 的作用域规则是什么

转载 作者:行者123 更新时间:2023-12-02 04:59:54 24 4
gpt4 key购买 nike

当我在 for 理解中使用 val 时,我收到警告:

warning: val keyword in for comprehension is deprecated

尽管规范的语法附录中有产生式。

这表明当我做类似的事情

for (x <- xs; a = x)

我并没有真正引入一个变量,比如我做了类似的事情

for (x <- xs) yield { implicit val a = x; /* more */ }

像往常一样,大括号开始一个新的作用域,我可以在其中引入一个新的 val,甚至一个新的隐式。

我到底用这个a做什么?

我正在消耗堆栈空间吗?堆?其他类型的别名?

最佳答案

像普通的val pat = expr定义中,等号左边的东西只是一个模式。

语法规范中的枚举器产生式表明 for-expr 中的子句可以是生成器 (a <- b) ,守卫if cond或 val def a = b .

可以是任意表达式的部分是 b (如 <-= 右侧所示)和条件。

Responder.exec利用条件执行任意代码,同时简单地评估 true .

这意味着您可以通过条件产生任意副作用:

// yucky, yet instructive
scala> val xs = List(1,2,3)
scala> def bar(implicit i: Int) = Some(i+1)
scala> implicit var imp: Int = 0
scala> for { a<-xs; if { imp=a; true }; b<-bar } yield b
res6: List[Int] = List(2, 3, 4)

类似地,val def 脱糖如下:

tmp <- xs
a = f(tmp) // some arbitrary function of tmp
// amounts to
(tmp, a) <- for (x@tmp <- xs) yield { val x0@a=f(tmp); (x, x0) }

等等,真的吗?

scala> def f(vs: List[Int]) = for (a <- vs; b = a+1) yield b
f: (vs: List[Int])List[Int]

您需要最近的 repl 才能执行此操作:

scala> :javap f
[snip]
public scala.collection.immutable.List<java.lang.Object> f(scala.collection.immutable.List<java.lang.Object>);
flags: ACC_PUBLIC

Code:
stack=3, locals=2, args_size=2
0: aload_1
1: new #16 // class $anonfun$f$1
4: dup
5: invokespecial #17 // Method $anonfun$f$1."<init>":()V
8: getstatic #22 // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
11: invokevirtual #26 // Method scala/collection/immutable/List$.canBuildFrom:()Lscala/collection/generic/CanBuildFrom;
14: invokeinterface #32, 3 // InterfaceMethod scala/collection/TraversableLike.map:(Lscala/Function1;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;
19: checkcast #28 // class scala/collection/TraversableLike
22: new #34 // class $anonfun$f$2
25: dup
26: invokespecial #35 // Method $anonfun$f$2."<init>":()V
29: getstatic #22 // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
32: invokevirtual #26 // Method scala/collection/immutable/List$.canBuildFrom:()Lscala/collection/generic/CanBuildFrom;
35: invokeinterface #32, 3 // InterfaceMethod scala/collection/TraversableLike.map:(Lscala/Function1;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;
40: checkcast #37 // class scala/collection/immutable/List
43: areturn

我看到两次对 map 的调用,分别用于中间表达式和yield。

经进一步检查,第一个 anonfun 不是 Int => Int (即 a+1 )但是 Int => (Int,Int) .

所以我们引入的 val 只是作为元组的一部分传递。

关于scala - Scala for 推导式中 val 的作用域规则是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14087014/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com