【问题标题】:Scala - how to go resolve "Value is not a member of Nothing" errorScala - 如何解决“值不是 Nothing 的成员”错误
【发布时间】:2013-08-02 03:56:14
【问题描述】:

此示例代码基于 Atmosphere 类,但如果有人能给我一些关于错误的一般含义的见解,我想我可以找出任何特定于 Atmosphere 的解决方案...

val bc = BroadcasterFactory.getDefault().lookup(_broadcasterId) 
bc.broadcast(message)

在第一行之后, bc 应该包含一个对象的句柄,该对象的类定义包含方法 broadcast() —— 事实上,它包含几个重载的变体。但是,编译器在第二行代码中阻塞了以下内容:“值广播不是 Nothing 的成员”

关于造成这种情况的任何想法/建议?

谢谢。

编辑:[BroadcasterFactor].lookup 的签名: 抽象广播者查找(对象 id)

注意:1) 这是我在示例中使用的签名版本,2) 它是 java Inteface 签名 - 而 getDefault() 交还一个实现该接口的实例化对象。

解决方案:强制类型强制转换:

val bc: Broadcaster = BroadcasterFactory.getDefault().lookup(_broadcasterId)

【问题讨论】:

  • 您能否在第 1 行发布 lookup 方法的签名。这很可能是问题所在。它返回一个 Nothing 而不是具有 broadcast 方法的任何东西。

标签: scala compilation atmosphere


【解决方案1】:

Nothing 是类型名称。它是所有其他类型的子类型。您不能从 Nothing 本身调用方法,您必须指定确切的类型 ((bc: ExactType).broadcast(message))。 Nothing 没有实例。返回Nothing 的方法实际上永远不会返回值。最终会抛出异常。

类型推断

Definition of lookup:

abstract public <T extends Broadcaster> T  lookup(Object id);

在 scala 中,这个定义是这样的:

def lookup[T <: Broadcaster](Object id): T

lookup 方法中没有指定类型参数。在这种情况下,编译器会将此类型参数推断为最具体的类型 - Nothing:

scala> def test[T](i: Int): T = ???
test: [T](i: Int)T

scala> lazy val x = test(1)
x: Nothing = <lazy>                                                                                                                                            

scala> lazy val x = test[String](1)                                                                                                                            
x: String = <lazy>

你可以像这样指定类型参数:

val bc = BroadcasterFactory.getDefault().lookup[Broadcaster](_broadcasterId) 

实施草案

在开发过程中lookup可以像这样“实现”:

def lookup(...) = ???

??? 返回Nothing

您应该指定lookup 方法的结果类型,如下所示:def lookup(...): &lt;TypeHere&gt; = ...bc 类型:val bc: &lt;TypeHere&gt; =

【讨论】:

  • 确实如此。它归结为编译器没有产生正确的类推断。我不会猜到 - 谢谢!
  • @mjk: java 接口不能在没有类型参数的情况下返回Nothing。您确定getDefaultlookup 中没有类型参数吗?我已经更新了我的答案。
  • 坦率地说,关于 Atmosphere 库,我不确定。我已经为它的集成奋斗了一个星期,并且非常高兴。也就是说,我从库源文件中挖出了这个:public final Broadcaster lookup(Object id),这反过来又使一个更健壮的调用其他覆盖之一。让我感到困惑的一件事是无法将这些调用链接在一起——但我对 Scala 的有限经验并没有让我能够告诉你更多。再次谢谢你。 -干杯
  • @mjk: inability to chain those calls together: 你应该指定类型参数:BroadcasterFactory.getDefault().lookup[Broadcaster](_broadcasterId).broadcast(message)
  • 在我遇到的所有不同示例中,对于库的所有不同版本,我都不记得曾经使用过那种形式的类型声明。更有趣的是,我在此处发布的代码是从 scala Web 框架的更大部分/示例中提炼出来的——它在那里工作得很好,但从我的代码库中提取和使用时就不行了。有什么想法会导致这种情况吗? (顺便说一句,我并不是说您的示例有任何错误,只是我从未见过其他人必须将这些声明注入他们的示例)
猜你喜欢
  • 1970-01-01
  • 2018-05-17
  • 2023-03-09
  • 1970-01-01
  • 2015-10-03
  • 2014-09-29
  • 2016-05-01
  • 2013-03-10
  • 2019-09-10
相关资源
最近更新 更多