2
我尝试过各种东西,做一些很简单的,我会做在Java中使用一个装饰图案,但希望在斯卡拉与可堆叠修改做失败了。完整性检查的特质
这是我用例:我实现一些简单的自动完成者。它们都实现基本特征:
trait AutoCompleter {
def topSuggestions(prefix: String): Iterator[String]
def update(sentence: String*): Unit
final def topSuggestions(prefix: String, n: Int): List[String] = topSuggestions(prefix).take(n).toList
}
其中有些是根据特里结构的一个自定义实现具体实现:
/**
* This auto-completer learns from the user's input, and therefore does not require a preliminary dictionary.
*/
class ParrotAutoCompleter extends AutoCompleter {
private val trie = new WeightedTrie[Char, String]()
override def topSuggestions(prefix: String): Iterator[String] = trie.prefixedBy(prefix)
override def update(sentence: String*): Unit = sentence.foreach(trie += _)
}
和其他一些人是可堆叠修改:
/**
* This auto-completer will try returning some suggestions when the prefix did not match any known word by dropping the
* last character until it finds a suggestion
*/
trait TolerantAutoCompleter extends AutoCompleter {
def MaxRetries: Int
abstract override def topSuggestions(prefix: String): Iterator[String] = {
if (MaxRetries < 1) throw new IllegalArgumentException("Should allow 1 retry minimum, but max retries was: " + MaxRetries)
for (attempt <- 0 to Math.min(prefix.length, MaxRetries)) {
val suggestions = super.topSuggestions(prefix.substring(0, prefix.length - attempt))
if (suggestions.hasNext) return suggestions
}
Iterator()
}
}
我使用它们像这样:
val autoCompleter = new ParrotAutoCompleter with TolerantAutoCompleter { override val MaxRetries: Int = 5 }
该实现工作正常,但存在一个缺陷:在MaxRetries
上执行的完整性检查只有在使用自动完成程序而不是创建它时才会执行。更奇怪的是,它每次都运行,而不是一次。
问题是,即使在MaxRetries
被覆盖之前(不管它是否被声明为val
或def
),在特征中方法之外的任何代码都会立即执行。
我怎么能执行,在施工时间我的理智检查,覆盖后,并没有失去作为一个可堆叠修改属性?
看来你的回答是正确的,但你的方式,我认为解释仍不清楚。我不确切知道你在描述这个流程的代码(虽然我想你只是在谈论我的代码段,只是你在特质的身体中移动了理智检查),而你的意思是“anon”。 。你能否澄清这两点? – Dici
使用'lazy val'来避免重新计算更为标准(尽管在文字的特定情况下,'def'会更好)。 –
@AlexeyRomanov我实际上试过在特质声明中使用'lazy',它没有编译,但我意识到我应该在特性的具体用法中使用它。这能解决问题吗(现在不能尝试)?如果是这样,你能否在这种情况下添加一个描述初始化顺序规则的答案? – Dici