加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – found单位:required Int.为什么错误不明显?

发布时间:2020-12-16 09:23:24 所属栏目:安全 来源:网络整理
导读:我有一个方法,应该返回一个Int.我试图理解为什么Eclipse不会让我编译这个,即使在if语句里面我看起来很明显,我确实返回了一个Int.有没有我失踪的东西很明显?在开始编写更多代码之前,我正在努力了解Scala的这一方面. 这是方法: def contains1(sfType: TokenT
我有一个方法,应该返回一个Int.我试图理解为什么Eclipse不会让我编译这个,即使在if语句里面我看起来很明显,我确实返回了一个Int.有没有我失踪的东西很明显?在开始编写更多代码之前,我正在努力了解Scala的这一方面.

这是方法:

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

Eclipse抱怨第二行—“类型不匹配;发现:所需单位:Int“

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

我已经在这里阅读了这篇文章:found: Unit required: Int – How to correct this?,并尝试在发布之前解决问题,但我仍然感到失落.

编辑:该方法应该返回一个Int,我输入错误的返回类型.我的问题依然如故Eclipse仍然抱怨.

解决方法

我会先解释一下Unit是什么,以防万一.即使你已经知道了,其他有同样问题的人也不会知道.

类型单位与C或Java中已知的类似于void.在这些语言中,这意味着“这不返回任何东西”.但是,Scala中的每个方法都返回一个值.

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

val x: Unit = ()

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

无论如何,如果你不想返回任何东西,你返回单位.

现在来看看给出的代码. Eclipse说它返回Unit,事实上Eclipse是正确的.然而,大多数人实际上会使该方法的错误返回AnyVal或Any而不是Unit.有关示例,请参阅以下代码段:

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

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

if (flag) x else y

显然,返回的值将是x或y,因此类型必须使x和y都适合.一个这样的类型是任何,因为一切都有类型Any.如果x和y都是相同的类型,例如Int,那么这也是一个有效的返回类型.由于Scala选择最具体的类型,所以选择Int over Any.

现在,当你没有其他语句时会发生什么?即使没有else语句,条件可能是假的 – 否则,使用if就没有意义.在这种情况下,Scala所做的是添加一个else语句.也就是说,它重写if语句如下:

if (true) 2 else ()

就像我之前说过的:如果你没有什么要回来的话,返回单位!这正是发生了什么.由于Int和Unit都是AnyVal,并且由于AnyVal比Any更具体,所以该行返回AnyVal.

到目前为止,我已经解释了其他人可能看到的内容,但不是在该问题的特定代码中会发生什么:

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

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

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

我们也看到,Scala将选择两种可能结果中最具体的类型.最后,Eclipse告诉使用返回类型是Unit,所以唯一可能的解释就是这样的类型:

val retVal = TokenTypes.RESERVED_WORD

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

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

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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读