是的,Some
将创建对象(None
是单例)。当然,除非 JVM 忽略了这一点——这取决于许多因素,包括 JVM 是否认为代码被调用了那么多。
无论如何,该代码并不是真正的标准习语。甚至还有一个梗:有一次,一位经验丰富的 Scala 开发人员编写了这样的代码,而另一位则回答:“这是什么?业余时间?Flatmap 太糟糕了!”
无论如何,这就是我将如何重写它:
( counts
get word
map (_.toDouble / total_tokens * (1.0 - unseen_mass))
getOrElse (
WordDist.overall_word_probs
get word
map (unseen_mass * _ / overall_unseen_mass)
getOrElse (unseen_mass * WordDist.globally_unseen_word_prob
/ WordDist.num_unseen_word_types)
)
)
然后你可以重构它——这两个getOrElse
参数可以用不同的方法用好名字分割。因为它们只是返回一个没有输入的值,所以它们应该很快。
现在,我们在Option
:map
和getOrElse
. 这是他们实施的开始:
@inline final def map
@inline final def getOrElse
由于参数 togetOrElse
是按名称传递的,因此它涉及匿名函数的创建。当然,参数 tomap
也是一个函数。除此之外,这些方法被内联的机会非常好。
所以,这是重构的代码,虽然我对它的了解还不够,无法给出好名字。
def knownWordsFrequency = counts get word map computeKnownFrequency
def computeKnownFrenquency =
(_: Int).toDouble / total_tokens * (1.0 - unseen_mass)
def probableWordsFrequency = (
WordDist.overall_word_probs
get word
map computeProbableFrequency
)
def computeProbableFrequency = unseen_mass * (_: Double) / overall_unseen_mass
def unknownFrequency = (unseen_mass * WordDist.globally_unseen_word_prob
/ WordDist.num_unseen_word_types)
def estimatedWordsFrequency = probablyWordsFrequency getOrElse unknownFrequency
knownWordsFrequency getOrElse estimatedWordsFrequency