【问题标题】:Scala Optional best practicesScala 可选的最佳实践
【发布时间】:2020-04-28 07:09:56
【问题描述】:
def canAppendOffset(offset: Long): Boolean = {
  toRelative(offset).isDefined
}

private def toRelative(offset: Long): Option[Int] = {
  val relativeOffset = offset - baseOffset
  if (relativeOffset < 0 || relativeOffset > Int.MaxValue) None
  else Some(relativeOffset.toInt)
}

遇到上述代码时,我感到很困惑。来自 Kafka LogSegment 的代码。我想知道为什么我们在这里需要一个 Optional 而不是简单地在 canAppendOffset() 中返回一个布尔值。对我来说,为什么我们需要创建一个 Optional 并访问一个记录我需要的布尔值的字段似乎没有必要。 我认为在软件设计方面一定有一些逻辑。任何人都可以就在哪里以及为什么在 Scala 中使用 Optional 提供任何建议吗?

【问题讨论】:

  • 请注意,Option 不仅仅用于处理null。 Option 表示缺失值或无法返回值的计算的效果。大多数语言使用null 处理这个问题;例如爪哇。这就是为什么 Option 的构造函数会捕获null。但是,(并鼓励)即使在没有 null 的情况下也可以返回可选值,这只是为了表明,这里的这个值可能存在也可能不存在。

标签: scala apache-kafka syntax utility


【解决方案1】:

这里似乎存在一些误解。

...创建一个 Optional 并访问一个记录布尔值的字段...

这里没有字段。 isDefined 是Option 类中的一个方法,用于测试此实例是Some() 还是None。

...为什么我们在这里需要一个 Optional 而不是简单地在 canAppendOffset() 中返回一个布尔值。

但是canAppendOffset() 确实“只是返回一个Boolean”。是toRelative()“创建”了Option,它这样做是因为,虽然应该从给定的偏移量返回一个“相对”,但如果一个有效的结果是不可能的。

所以它返回一个Option[Int],从而告诉调用者,“这里是Some(relative),如果它可以从给定的偏移量计算,但它是None,如果我不能为你计算一个好的结果。”

【讨论】:

  • isDefined 的描述有点误导。 isDefined 可用于测试Option 的实例,但该方法本身不测试任何内容,它只是返回一个常量。
  • 嗨@Tim。在发帖之前我访问了source,因为def isDefined 是!isEmpty,而def isEmpty 是this eq None,我认为描述非常准确。哪里说的不变?
  • @jwvh 感谢您的澄清,是的,我明白了,isDefined 是一种方法。我理解您所说的使用 Optional 的原因。但是这里似乎如果条件不满足,可以简单地返回一个错误,因为isRelative() 中没有错误返回。我认为如果有机会调用 NullPointerException 之类的东西,Optional 会很有用,但这里似乎不存在这种风险。
  • 我知道canAppend 只是返回一个布尔值,我想知道的是为什么它不简单地在其内部进行条件检查,额外的isRelative() 对我来说似乎有点多余。
  • @BoyuZhang;你的意思是为什么不在canAppendOffset() 内部进行relativeOffset 计算和测试并完成它,正如@YuvalItzchadov 在他的回答中所建议的那样?实际上,将toRelative() 从图片中删除会更有效,但是您有重复的代码来确定给定的偏移量是否有效。如果有效偏移量的定义发生变化怎么办?然后你必须在代码库中寻找完成计算的两个地方。这些是软件设计师必须做出的权衡。
【解决方案2】:

在我看来,为什么我们需要创建一个 Optional 和 访问记录我需要的布尔值的字段。

我同意。如果在实际使用计算出的偏移量的其他地方使用它将创建一个返回Option[Int] 的toRelative 方法是有意义的。很可能该方法以前用于其他用例,并了解实际使用的相对偏移量。

如果您只想知道是否可以附加偏移量,您可以简化:

private def canAppendOffset(offset: Long): Boolean = {
  val relativeOffset = offset - baseOffset
  relativeOffset >= 0 && relativeOffset < Int.MaxValue
}

【讨论】:

    猜你喜欢
    • 2014-11-18
    • 1970-01-01
    • 2020-04-04
    • 1970-01-01
    • 2013-07-07
    • 1970-01-01
    • 2019-05-23
    • 2017-12-19
    • 2013-09-10
    相关资源
    最近更新 更多