在 Scala 中使用类变量作为常量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/803206/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 01:25:40  来源:igfitidea点击:

Use Class Variables As Constants In Scala

syntaxscala

提问by Onorio Catenacci

I'm working to learn Scala--coming from a C++ background. I am trying to write a small class for a task tracking app I'm hacking together to help me to learn how to code Scala.

我正在努力学习 Scala——来自 C++ 背景。我正在尝试为一个任务跟踪应用程序编写一个小类,我正在一起编写代码以帮助我学习如何编写 Scala 代码。

This seems as if it should be simple but for some reason it's eluding me:

这似乎应该很简单,但由于某种原因,我无法理解:

package com.catenacci.tts

class Task(val ID:Int, val Description:String) {
 val EmptyID = 0
 val EmptyDescription = "No Description"

 def this() = this(EmptyID,EmptyDescription)
 def this(ID:Int)={
   this(ID,EmptyDescription)
 }
 def this(Description:String)={
   this(EmptyID,Description)
 }
}

I'm trying to provide three constructors: Task(ID, Description), Task(ID), Task(Description). In the latter 2 cases I want to initialize the values to constant values if one of the values isn't provided by the caller. And I want to be able to check this outside of the class for unit testing purposes. So I figured putting in two public vals would allow me to check from outside of the class to make sure that my state is what I expect.

我试图提供三个构造函数:Task(ID, Description)、Task(ID)、Task(Description)。在后两种情况下,如果调用者未提供其中一个值,我想将这些值初始化为常量值。而且我希望能够在课堂之外进行检查以进行单元测试。所以我认为放入两个公共 val 可以让我从课堂外进行检查,以确保我的状态是我所期望的。

However, for some reason this code will not compile. I get the following error:

但是,由于某种原因,此代码无法编译。我收到以下错误:

error: not found: value EmptyID

and

error: not found: value EmptyDescription

So what am I missing? I'm working through "Programming in Scala" so if there's a simple answer to this question, please give me page numbers. I don't mind reading but going by the code on page 60 and page 62, I can't see why this code is failing.

那么我错过了什么?我正在研究“Scala 编程”,所以如果这个问题有一个简单的答案,请给我页码。我不介意阅读,但是按照第 60 页和第 62 页的代码,我不明白为什么这段代码会失败。

I'm guessing it has something to do with the fact that these are constructor methods and that possibly the two vals are not initialized until the end of the constructors. If that's the case is there some way to get the effect I'm looking for?

我猜这与以下事实有关,即这些是构造函数方法,并且可能两个 val 直到构造函数结束才初始化。如果是这种情况,有什么方法可以获得我正在寻找的效果吗?

回答by Germán

You can define the constants in a companion object:

您可以在伴随对象中定义常量:

object Task { 
 val EmptyID = 0
 val EmptyDescription = "No Description"
}

And then reference them as Task.EmptyID and Task.EmptyDescription.

然后将它们引用为 Task.EmptyID 和 Task.EmptyDescription。

I think Scala 2.8 has support for default values.

我认为 Scala 2.8 支持默认值。

回答by Daniel Spiewak

See Germán for the answer. This happens because a constructor is technicallypart of the static scope. In other words, the constructor cannot access any instance members because the instance hasn't been created yet. Any "class members" are actually instance members, which is why the code in the question does not work. Germán's answer fixes this by moving the two relevant values into the companion object, which effectively makes them static members of the Taskclass (not really, but you can think of it that way).

请参阅 Germán 以获取答案。发生这种情况是因为构造函数在技术上是静态作用域的一部分。换句话说,构造函数不能访问任何实例成员,因为实例还没有被创建。任何“类成员”实际上都是实例成员,这就是问题中的代码不起作用的原因。Germán 的回答通过将两个相关值移动到伴随对象中来解决这个问题,这有效地使它们成为Task类的静态成员(不是真的,但你可以这样想)。

回答by Don Mackenzie

In "Programming in Scala", see section 6.7 where the chaining of constructor calls is explained. The primary constructor is described as "the single point of entry of a class".

在“Scala 编程”中,请参阅第 6.7 节,其中解释了构造函数调用的链接。主构造函数被描述为“类的单一入口点”。