scala - Scala:不可参数化提取器的解决方法
问题描述
由于提取器不能采用自定义参数(如Stack Overflow 中的回答:可以自定义提取器...),我尝试找到解决以下问题的替代方法。
我有很多可以组合的翻译。在我的代码片段中,维度可以与因子结合。例如"width multiplied by 2"
. 但它也可以是"width"
(不相乘的)。而且还会有更多类似的案例。我尝试使用模式匹配对这些字符串输入进行分类。"width"
并"width multiplied by x"
应归类为“宽度”(key "w"
),"height"
应"height multiplied by x"
归类为“高度”(key "h"
),以此类推。
这应该由match
以下示例代码片段中的最后一个完成,该示例代码片段将包含许多案例(示例代码片段中的 6 个),每个案例都应带有一个key: String
参数("w"
, "h"
, "l"
, "r"
, "t"
, "b"
)。
我试图实现的是将密钥(即"w"
, "h"
, "l"
, "r"
, "t"
,"b"
等)传递给 case Untranslation(v)
。但显然我不能这样做(该unapply
函数可以采用隐式参数,但没有额外的显式参数)。
现在我尝试找到一种替代但仍然简洁的方式来对我的字符串输入进行分类。
implicit val translations = Map(
"w" -> "width",
"h" -> "height",
"l" -> "left",
"r" -> "right",
"t" -> "top",
"b" -> "bottom",
// + some more translations
"m" -> "multiplied by"
)
sealed trait CommandType
object CommandType {
case object Unmodified extends CommandType
case object Multiplied extends CommandType
// ...
}
object Untranslation {
def unapply(s: String)(implicit t: Map[String, String]): Option[CommandType] = {
val key: String = "w" // should be variable by case
val a: List[String] = t(key).split(" ").toList
val b: List[String] = t("m").split(" ").toList
val ab: List[String] = a ++ b
s.split(" ").toList match {
case `a` => Some(CommandType.Unmodified)
case `ab` :+ value => Some(CommandType.Multiplied)
// + some more cases
case _ => None
}
}
}
"width multiplied by 2" match {
case Untranslation(v) => println(v) // here I would like to pass the key ("w"/"h"/"l"/...)
case _ => println("nothing found")
}
// outputs: Multiplied
解决方案
您可以轻松地为提取器创建参数化class
而不是object
:
class Untranslation(val key: String) {
def unapply(s: String)(implicit t: Map[String, String]): Option[CommandType] = {
val a: List[String] = t(key).split(" ").toList
val b: List[String] = t("m").split(" ").toList
val ab: List[String] = a ++ b
s.split(" ").toList match {
case `a` => Some(CommandType.Unmodified)
case `ab` :+ value => Some(CommandType.Multiplied)
// + some more cases
case _ => None
}
}
}
To match
,提取器需要有一个稳定的标识符,这可以通过将其分配给 a 来完成val
(因此不幸的是,每个键都需要额外的一行,但它们当然可以在多个匹配中使用):
val UntranslationW = new Untranslation("w")
val UntranslationT = new Untranslation("t")
...
"width multiplied by 2" match {
case UntranslationW(v) => ...
case UntranslationT(v) => ...
case _ => println("nothing found")
}
推荐阅读
- javascript - 我的经济指挥出错了,你能帮帮我吗?
- linux - 在 64 位机器(gcc、docker)上使用 -m32 构建 32 位程序时找不到 -lgcc
- macos - 在命令行中使用 ohmyzzh 导入 macOS 主题
- java - 使用自定义 GraphQL 查询通过 SPQR (Java) 解析嵌套字段
- c++ - xcode ios项目,如何从其他目录导入cpp代码文件?
- javascript - 在 Chrome 扩展中使用 Javascript 来检测 Android 浏览器 WebView 方案?
- r - 更改输入时闪亮会抛出警告:错误:无法提取不存在的列
- reactjs - 反应输入状态不清楚如何清除输入状态
- python - MySQL 错误消息:“1054 (42S22): 'field list' 中的未知列 'inf'”
- c++ - 如何从多个字符串变量中声明一个字符串 C++