当前位置: 首页 > 知识库问答 >
问题:

使用类中的嵌套方法避免“任务不可序列化”

陆伟
2023-03-14

我理解访问超出闭包范围的字段或方法时出现的通常的“任务不可序列化”问题。

为了修复它,我通常定义这些字段/方法的本地副本,这避免了序列化整个类的需要:

class MyClass(val myField: Any) { 
  def run() = { 
    val f = sc.textFile("hdfs://xxx.xxx.xxx.xxx/file.csv") 

    val myField = this.myField 
    println(f.map( _ + myField ).count) 
  } 
} 

现在,如果我在run方法中定义一个嵌套函数,它将无法序列化:

class MyClass() { 
  def run() = { 
    val f = sc.textFile("hdfs://xxx.xxx.xxx.xxx/file.csv") 

    def mapFn(line: String) = line.split(";") 

    val myField = this.myField 
    println(f.map( mapFn( _ ) ).count) 

  } 
} 

我不明白,因为我以为“mapFn”会在范围内。。。更奇怪的是,如果我将mapFn定义为val而不是def,那么它是有效的:

js prettyprint-override">class MyClass() { 
  def run() = { 
    val f = sc.textFile("hdfs://xxx.xxx.xxx.xxx/file.csv") 

    val mapFn = (line: String) => line.split(";") 

    println(f.map( mapFn( _ ) ).count)     
  } 
} 

这与Scala表示嵌套函数的方式有关吗?

处理这个问题的推荐方法是什么?避免嵌套函数?

共有1个答案

许远航
2023-03-14

在第一种情况下,f.map(mapFN())与f.map(new Function(){override def apply(…)=mapFN(…)}) f.map(mapFN)?当您使用def声明一个方法时,它可能只是某个匿名类中的一个方法,该类对封闭类具有隐式$outer引用。但是map需要一个函数,因此编译器需要对其进行包装。在包装器中,您只引用该匿名类的某些方法,而不是实例本身。如果使用val,则直接引用传递给映射的函数。我不确定,只是想大声说出来。。。

 类似资料:
  • 问题内容: 避免嵌套查询有多重要。 我一直学会避免像瘟疫一样躲避它们。但是对我来说,它们是最自然的事情。在设计查询时,我首先写的是嵌套查询。然后,我将其转换为联接,有时需要花费很多时间才能正确。而且很少会带来很大的性能提升(有时确实会提高) 他们真的那么糟糕吗?有没有一种方法可以使用没有临时表和文件排序的嵌套查询 问题答案: 这确实取决于我遇到的情况,我可以通过使用子查询来改进一些查询。 我知道的

  • 问题内容: 我需要确保许多并发用户能够访问数据库。虽然在每次提交后我都关闭了会话,但是有时我的代码遇到以下错误,但是当我几次执行相同的操作时,它会超过错误并可以正常工作。 我的hibernate状态是4.2.1。 我的密码 HibernateUtil 组态 问题答案: 在您的“我的代码”代码段中,可能存在一些问题: 发生异常时,没有阻止关闭会话的块 您正在打电话,但这与有所不同。因此,不会清除。

  • 在我的程序中,我有一个返回一些RDD的方法,我们称它为,它接受一个不可序列化的参数,并让RDD的类型为(我真正的RDD是元组类型,但只包含基元类型)。 当我尝试这样的事情时: 我得到的。 当我用替换(即某个常数)时,它会运行。 从序列化跟踪中,它试图序列化,并在那里阻塞,但我仔细检查了我的方法,这个对象从未出现在RDD中。 当我试图直接收集的输出时,即 我也没有问题。 该方法使用获取(本地)值序列

  • 问题内容: 这更多是出于好奇/科学兴趣,而不是基于真正的问题,我曾经问过数据库讲师这件事,但是他无法回答/理解我的问题。所以我决定过来这里。 编程语言应该是一种工具,并且可以使工作变得更容易,对吗?因此,为什么只需执行一次操作就可以在一个表中找到所有条目。但是,一旦涉及到多个表,就没有简单/直观的方式说“找到满足此条件的所有元组”吗? 脚本中给定的示例是这样的(这是从德语翻译的,因此命名可能会有些

  • 考虑: 如果我们序列化Foo(),输出是: 我想要: 最干净的方法是什么?

  • 问题内容: 我已经从JUnit3.8切换到JUnit4.4。我使用ant运行测试,所有测试均成功运行,但测试实用程序类失败,并显示“无可运行方法”错误。我使用的模式是在测试文件夹下包括所有名称为 Test 的类。 我知道,运行程序找不到任何带有@Test属性注释的方法。但是它们不包含此类注释,因为这些类不是测试。令人惊讶的是,当在Eclipse中运行这些测试时,它不会抱怨这些类。 在JUnit3.