找到单位:必需的 Int.为什么错误不明显? [英] found Unit: required Int. Why is the error not obvious?

查看:46
本文介绍了找到单位:必需的 Int.为什么错误不明显?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应该返回 Int 的方法.我试图理解为什么 Eclipse 不允许我编译它,即使在 if 语句中我看起来很明显我确实返回了一个 Int.有什么我很明显的遗漏吗?在继续编写更多代码之前,我试图了解 Scala 的这一方面.

I have a method that is supposed to return an Int. I am trying to understand why Eclipse won't let me compile this, even though it looks apparent to me inside the if statement that I am indeed returning an Int. Is there something I am missing very obvious? I am trying to understand this aspect of Scala before proceeding to write more code.

方法如下:

def contains1(sfType: TokenType): Int = {
     if (Tokens.KEYWORDS.contains(sfType)) {
      val retVal = TokenTypes.RESERVED_WORD
    }
  }

Eclipse 在第 2 行抱怨 --- 'type mismatch;找到:所需单位:整数"

Eclipse complains on line 2 --- 'type mismatch; found : Unit required: Int"

TokenTypes is - public abstract interface org.fife.ui.rsyntaxtextarea.TokenTypes and RESERVED_WORD is - public static final int RESERVED_WORD = 6;

我在这里阅读了这篇文章:发现:需要的单位:Int - 如何更正?并尝试在发布之前解决问题,但我仍然不知所措.

I have read this post here: found: Unit required: Int - How to correct this? and tried to solve the problem before posting it, but I am still at a loss.

该方法应该返回一个 Int 并且我错误地输入了返回类型.我的问题还是一样.Eclipse 仍然抱怨.

The method is supposed to return an Int and I had typed in the return type wrongly. My problem remains the same. Eclipse still complains.

推荐答案

为了以防万一,我先解释一下 Unit 是什么类型.即使您已经知道,其他遇到相同问题的人也可能不知道.

I'll first explain what type Unit is, just in case. Even if you know already, other people having the same kind of problem might well not know it.

Type Unit 类似于在 C 或 Java 中称为 void 的内容.在这些语言中,这意味着这不会返回任何内容".但是,Scala 中的每个方法都返回一个值.

Type Unit is similar to what is known in C or Java as void. In those languages, that means "this does not return anything". However, every method in Scala returns a value.

为了弥补每个方法返回一些东西和没有任何有用的东西返回之间的差距,有Unit.这种类型是 AnyVal,这意味着它不会在堆上分配,除非它被装箱或者是对象上的字段类型.此外,它只有一个值,其字面量是().也就是说,你可以这样写:

To bridge the gap between every method returning something and not having anything useful to return, there's Unit. This type is an AnyVal, which means it isn't allocated on the heap, unless it gets boxed or is the type of a field on an object. Furthermore, it has only one value, whose literal is (). That is, you could write this:

val x: Unit = ()

这样做的实际效果是,当一个方法返回"Unit 时,编译器实际上不必返回任何值,因为它已经知道该值是什么.因此,它可以通过在字节码级别将它们声明为 void 来实现返回 Unit 的方法.

The practical effect of this is that, when a method "returns" Unit, the compiler doesn't have to actually return any value, since it already knows what that value is. Therefore, it can implement methods returning Unit by declaring them, on the bytecode level, as being void.

不管怎样,如果你不想返回任何东西,你就返回Unit.

Anyway, if you don't want to return anything, you return Unit.

现在让我们看看给出的代码.Eclipse 说它返回Unit,事实上,Eclipse 是正确的.然而,大多数人实际上会犯错误,让该方法返回 AnyValAny,而不是 Unit.有关示例,请参见以下代码段:

Now let's look at the code given. Eclipse says it returns Unit, and, in fact, Eclipse is correct. However, most people would actually make the error of having that method return AnyVal or Any, not Unit. See the following snippet for an example:

scala> if (true) 2
res0: AnyVal = 2

那么,发生了什么?好吧,当 Scala 找到一个 if 语句时,它必须弄清楚它返回的类型是什么(在 Scala 中,if 语句也返回值).考虑以下假设线:

So, what happened? Well, when Scala finds an if statement, it has to figure out what is the type returned by it (in Scala, if statements return values as well). Consider the following hypothetical line:

if (flag) x else y

很明显,返回的值要么是x 要么是y,所以类型必须是xy 将适合.其中一种类型是 Any,因为 everything 的类型为 Any.如果 xy 的类型相同——比如说,Int——那么这也是一个有效的返回类型.由于 Scala 选择最具体的类型,它会选择 Int 而不是 Any.

Clearly, the returned value will be either x or y, so the type must be such that both x and y will fit. One such type is Any, since everything has type Any. If both x and y were of the same type -- say, Int -- then that would also be a valid return type. Since Scala picks the most specific type, it would pick Int over Any.

现在,如果您没有else 语句会发生什么?即使没有else 语句,条件也可能为假——否则,使用if 就毫无意义.在这种情况下,Scala 所做的是添加一个else 语句.也就是说,它像这样重写 if 语句:

Now, what happens when you don't have an else statement? Even in the absence of an else statement, the condition may be false -- otherwise, there would be no point in using if. What Scala does, in this case, is to add an else statement. That is, it rewrites that if statement like this:

if (true) 2 else ()

就像我之前说的:如果你没有任何东西要返回,就返回Unit!这正是发生的事情.由于 IntUnit 都是 AnyVal,并且鉴于 AnyValAny 更具体code>,该行返回 AnyVal.

Like I said before: if you do not have anything to return, return Unit! That is exactly what happens. Since both Int and Unit are AnyVal, and given that AnyVal is more specific than Any, that line returns AnyVal.

到目前为止,我已经解释了其他人可能看到的内容,但没有解释问题中特定代码中发生的情况:

So far I have explained what others might have seen, but not what happens in that specific code in the question:

if (Tokens.KEYWORDS.contains(sfType)) {
  val retVal = TokenTypes.RESERVED_WORD
}

我们已经看到 Scala 会像这样重写它:

We have seen already that Scala will rewrite it like this:

if (Tokens.KEYWORDS.contains(sfType)) {
  val retVal = TokenTypes.RESERVED_WORD
} else ()

我们看到 Scala 会在两个可能的结果之间选择最具体的类型.最后Eclipse告诉use返回类型是Unit,所以唯一可能的解释就是this的类型:

We have also seen that Scala will pick the most specific type between the two possible results. Finally, Eclipse tells use that the return type is Unit, so the only possible explanation is that the type of this:

  val retVal = TokenTypes.RESERVED_WORD

也是 Unit.这是完全正确的:在 Scala 中声明事物的语句具有 Unit 类型.而且,顺便说一下,做作业.

is also Unit. And that's precisely correct: statements that declare things in Scala have type Unit. And, so, by the way, do assignments.

正如其他人指出的那样,解决方案是删除赋值并添加一个 else 语句,同时返回一个 Int:

The solution, as others have pointed out, is to remove the assignment and add an else statement also returning an Int:

def contains1(sfType: TokenType): Int =
  if (Tokens.KEYWORDS.contains(sfType)) TokenTypes.RESERVED_WORD
  else -1

(注意:我重新格式化了该方法以遵循 Scala 程序员中更常见的编码风格)

(note: I have reformatted the method to follow the coding style more common among Scala programmers)

这篇关于找到单位:必需的 Int.为什么错误不明显?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆