scala - scala:匹配情况下的“块不能包含声明”
问题描述
我有以下函数,它给了我错误:块不能包含声明这段代码有什么问题?
def max[A](tree: Tree[A])(func: (A, A) => Int): A = tree match {
case Leaf(value) => value
case Branch(value, left, right) => {
val leftMax = max(left)(func)
val rightMax = max(right)(func)
var currMax: A // block cannot contain declarations
if (func(leftMax, rightMax) > 0) {
currMax = leftMax
} else {
currMax = rightMax
}
if (func(value, currMax) > 0) {
currMax = value
}
currMax
}
}
解决方案
考虑声明和定义的区别
var x: Int // declaration: variable named x is of type Int
var x: Int = 42 // definition: variable named x is of type Int and refers to value 42
请注意,纯声明如何简单地说明变量的类型,但没有说明它的值。另一方面,定义既是一种声明,又是将一个具体的值与变量相关联。我们可以在特征或抽象类中使用纯声明,例如,
trait Foo {
var x: Int // pure declaration
}
object MyFoo extends Foo {
override var x: Int = 42
}
但是我们不能将它们放在块表达式中,例如
{
var x: Int // error: only traits and abstract classes can have declared but undefined members
"hello world"
}
说明声明和定义之间的区别,考虑当我们声明变量时在字节码级别会发生什么x
scala> trait Foo { val x: Int }
defined trait Foo
scala> :javap -c -filter Foo
Compiled from "<console>"
public interface Foo {
public abstract int x();
}
与我们定义变量时相比x
scala> trait Foo { val x: Int = 42 }
defined trait Foo
scala> :javap -c -filter Foo
Compiled from "<console>"
public interface Foo {
public abstract void $line4$$read$Foo$_setter_$x_$eq(int);
public abstract int x();
public static void $init$(Foo);
Code:
0: aload_0
1: bipush 42
3: invokeinterface #23, 2 // InterfaceMethod $line4$$read$Foo$_setter_$x_$eq:(I)V
8: return
}
注意在声明的情况下没有生成代码指令,而在定义的情况下有实际的指令,例如bipush 42
. 因此,声明只是编译器感兴趣的东西,而定义也会导致具体的运行时内存操作。
推荐阅读
- php - 使用 codeigniter 在每个用户类型的用户仪表板中显示公告
- airflow - 气流策略:如何定义和配置?
- apache-kafka - Kafka 主题过滤与微服务请求/回复模式的临时主题
- json - JSON 数据建模:有权访问项目的用户
- ruby-on-rails - 如何使用 ActiveRecord 中另一个表的列检索一个表的所有以及另一个表中的所有连接记录
- swift - 在集合视图中使用执行 segue
- ios - 我可以在不将联系人保存到 contactStore 的情况下使用 View CNContactViewController 吗?
- sse - 使用 SSE/AVX/AVX2 检查 __m128i 的所有字节是否匹配单个字节
- javascript - SocketIO 在 Heroku 环境中不工作 [在 Localhost 中工作]
- excel - Excel不断崩溃 - 梳理文件