是否有任何Scala技巧可以启用与地图键的模式匹配?换句话说,我想在Map实例旁边有一个提取器也接受一个键值,这意味着只有当matchable值是Map的一个实例并且有一个带有给定键的条目时,我希望这个模式匹配在其中,此条目的值受递归模式匹配的影响.
像这样的东西:
myMap match {
case MyMap("a")(a) => // do smth with value a
case MyMap("b")(MyMap("c")(c)) => // do smth with value c
}
Run Code Online (Sandbox Code Playgroud)
更新:
我找到了一些接近目标的方法,但它仍然不完美,因为它意味着合成键值持有者的定义:
case class MapKey[K](key: K) {
def unapply(o: Any) = o match {
case m: Map[K, _] ? m.get(key)
case _ ? None
}
}
val m1 = Map("a" ? "aa", "b" ? Map("c" ? "cc"))
val m2 = Map("a" ? "aa", "d" ? "dd")
val b = MapKey("b")
val c = MapKey("c")
val d …Run Code Online (Sandbox Code Playgroud) 似乎嵌套匹配不起作用,这是一个奇怪的限制.
行为的一个例子如下:
Some(Some(1),2) match {
| case Some(Some(a),b) => a
| case e => e
| }
<console>:9: error: wrong number of arguments for <none>: (x: (Some[Int], Int))Some[(Some[Int], Int)]
case Some(Some(a),b) => a
^
<console>:9: error: not found: value a
case Some(Some(a),b) => a
^
Run Code Online (Sandbox Code Playgroud)
这有效:
Some(Some(1),2) match {
case Some(a) => a match {
case (Some(a),b) => "yay"
case e => "nay"
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我只是一个蠢货还是有更好的方法来实现这一目标?
根据scala规范,由case类构建的提取器如下(scala规范§5.3.2):
def unapply[tps](x: c[tps]) =
if (x eq null) scala.None
else scala.Some(x.xs11, ..., x.xs1k)
Run Code Online (Sandbox Code Playgroud)
出于实现原因,我希望能够在非案例类上模仿此提取器的行为.但是,我的实现无法重现相同的行为.
以下是我的差异示例:
trait A
sealed trait B[X <: A]{ val x: X }
case class C[X <: A](x: X) extends B[X]
class D[X <: A](val x: X) extends B[X]
object D {
def unapply[X <: A](d: D[X]): Option[X] =
if (d eq None) None
else Some(d.x)
}
def ext[X <: A](b: B[X]) = b match {
case C(x) => Some(x)
case D(x) => Some(x)
case _ …Run Code Online (Sandbox Code Playgroud) 我定义了一个自定义提取器来获取列表的最后一个元素,如/sf/answers/468842461/:
object :+ {
def unapply[A](l: List[A]): Option[(List[A], A)] = {
if (l.isEmpty)
None
else
Some(l.init, l.last)
}
}
Run Code Online (Sandbox Code Playgroud)
现在这匹配"好":
List(1, 2, 3) match {
case init :+ last => "good"
case head :: tail => "bad"
}
Run Code Online (Sandbox Code Playgroud)
但如果我添加另一个条款,它现在突然匹配"坏":
List(1, 2, 3) match {
case List(7) => "never"
case init :+ last => "good"
case head :: tail => "bad"
}
Run Code Online (Sandbox Code Playgroud)
这种行为的原因是什么?
我正在尝试将REST API的响应建模为案例类,我可以使用模式匹配.
我认为这是一个很好的假设继承,但我看到这是不赞成的.我知道已经存在与案例类和继承相关的问题,但我的问题更多的是关于如何在没有继承的情况下在这里建模"正确的方法" .
我从以下两个案例类开始,它们工作正常:
case class Body(contentType: String, content: String)
case class Response(statusCode: Int, body: Body)
Run Code Online (Sandbox Code Playgroud)
即REST调用将返回类似于:
Response(200, Body("application/json", """{ "foo": "bar" }"""))
Run Code Online (Sandbox Code Playgroud)
我可以模仿匹配,如:
response match {
case Response(200, Body("application/json", json)) => println(json)
case Response(200, Body("text/xml", xml)) => println(xml)
case Response(_,_) => println("Something unexpected")
}
Run Code Online (Sandbox Code Playgroud)
等工作正常.
我遇到麻烦的地方是:我想要这些案例类的帮助扩展,例如:
case class OK(body: Body) extends Response(200, body)
case class NotFound() extends Response(404, Body("text/plain", "Not Found"))
case class JSON(json: String) extends Body("application/json", json)
case class XML(xml: String) extends Body("text/xml", …Run Code Online (Sandbox Code Playgroud) 我真的没有得到这个小东西.我有一个抽象类Box,有几个不同类型的子类.例如
abstract class Box
class StringBox(val sValue : String) extends Box
Run Code Online (Sandbox Code Playgroud)
Box的伴侣对象中的apply方法很简单:
object Box{
def apply(s: String) = new StringBox(s)
def apply(b: Boolean) = new BooleanBox(b)
def apply(d: Double) = new DoubleBox(d)
}
Run Code Online (Sandbox Code Playgroud)
所以我可以写
val sb = Box("StringBox)
Run Code Online (Sandbox Code Playgroud)
好的,写不应用会带来一些麻烦.我的第一个想法是在类型上使用模式匹配,如下所示:
def unapply(b: Box) = b match {
case sb: StringBox => Some(sb.sValue)
case bb: BooleanBox => Some(bb.bValue)
case db: DoubleBox => Some(db.dValue)
case _ => None
Run Code Online (Sandbox Code Playgroud)
}
由于类型擦除,这根本不起作用.
第二次尝试是具有类型T的通用Box [T],并且在每个子类中重新定义了抽象类型成员.例如:
abstract class Box[T] {def value : T}
class StringBox(val sValue : …Run Code Online (Sandbox Code Playgroud) 我有以下case类和一个默认参数,我想知道如何编写一个unapply方法,以便我可以只提取前两个参数.
我希望下面的代码是清楚的.
case class Point(x: Double, y: Double, _key: Option[String] = None) {
def key: String = _key.getOrElse("")
}
object Point {
def unapply(p: Point) = (p.x, p.y)
}
// pSeq is Seq[Point]
pSeq.map { case Point(x,y) => x + y } // This causes a compiler error:
// wrong number of arguments for <none>:
// (x: Double, y: Double, _key: Option[String])
Run Code Online (Sandbox Code Playgroud) 我正在尝试从正文响应中提取访问令牌,并在 Header Manager 中使用它进行授权。第一个请求的响应是 Response
然后我使用正则表达式来提取令牌 Json Extractor
然后我在 Header Manager Header Manager 中输入一个变量
但是当我运行脚本时,我收到一个错误: 监听器
另外,我收到一个错误:
2019-02-09 23:45:57,822 ERROR o.a.j.e.j.j.JSONPostProcessor: Error processing JSON content in JSON Extractor, message: Use bracket notion ['my prop'] if your property contains blank characters. position: 2
错误
我假设 json 路径不正确
我已经在这里研究了很多问题,但它们没有帮助我 我的行为有什么问题?感谢您提前回复!
想象一下以下代码:
class SimpleLetter
def values
("a" .. "z").to_a
end
def ===(other)
values.include?(other)
end
end
class Vowel < SimpleLetter
def values
["a","e","i","o","u"]
end
end
class Consonant < SimpleLetter
def values
super - Vowel.new.values
end
end
objects = ("a" .. "f").to_a + (1 .. 5).to_a
objects.each do |letter|
case letter
when Vowel.new
puts "#{letter} it's a vowel"
when Consonant.new
puts "#{letter} it's a consonant"
else
puts "#{letter} it's something else"
end
end
Run Code Online (Sandbox Code Playgroud)
我可以选择任何其他类,我只是以它们为例.我非常喜欢Scala match和提取器,我认为这可能是在Ruby中编写相同内容的好方法.有没有更好的方法来编写上面的内容而不必实例化新对象只是为了我可以调用他们的===方法?
只是为了避免不必要的帖子,是的,我知道我可以这样做:
case letter
when ["a","e","i","o","u"].include?(letter) …Run Code Online (Sandbox Code Playgroud) 使用Apache JMeter ver 3.2 r1790745(最新版本)测试JSON Web服务,响应如下:
[ {
"id" : 3,
"description" : "Back",
"name" : "back"
}, {
"id" : 1,
"description" : "Front",
"name" : "front"
}, {
"id" : 6,
"description" : "Left",
"name" : "left"
}]
Run Code Online (Sandbox Code Playgroud)
想要解析上面的响应,以便在JSON Extractor中将所有ID都放在一个字符串中,比如
3,1,6
Run Code Online (Sandbox Code Playgroud)
我的JSON Path表达式是这样的:
$..id
Run Code Online (Sandbox Code Playgroud)
但我只获得了第一个id为3,与$.[0].id
在BeanShell PostProcessor中检查结果的结果相同.如果我去http://jsonpath.com/
$ ..我确实给了我
[
3,
1,
6
]
Run Code Online (Sandbox Code Playgroud) extractor ×10
scala ×8
case-class ×3
jmeter ×2
json ×2
case ×1
match ×1
ruby ×1
scala-option ×1
unapply ×1