[英]How to use variable declared in pattern-matching case class?
I have the following trait: 我具有以下特征:
sealed trait Tr
case class Test1(str: String) extends Tr
Now I want to use str
in my code. 现在,我想在代码中使用str
。
val tr: Tr = //...
tr match {
case Test1(str) =>
val str = //str declared in Test1(str) + "some another string"
}
Is it possible to directly refer to the str
preserving the name str
. 是否有可能直接引用str
保留名称str
。 I can use something like 我可以使用类似
tr match {
case test1 @ Test1(str) =>
str = test1.str + "some another string"
}
But this seems ugly to me. 但这对我来说似乎很丑。
str
is immutable. str
是不可变的。 Try another variable. 尝试另一个变量。
If you want to edit a case class try: 如果要编辑案例类,请尝试:
val test2 = test1.copy(str = test1.str + "some another string")
This will create a new instance, not mutate the case class
. 这将创建一个新实例,而不会使case class
突变。
You don't need the email operator: 您不需要电子邮件运营商:
sealed trait Tr
case class Test1(str: String) extends Tr
val tr = Test1 ("foo")
tr match {
case Test1 (str) => println (str)
}
foo
Of course, reassignment to str isn't possible. 当然,不可能将其重新分配给str。
Note, that in most cases, the parameter of a class has a meaning, and in an ideal world, one of few best meanings, so the stimulus, to repeat the same variable name is high. 请注意,在大多数情况下,类的参数具有含义,并且在理想情况下,为数不多的最佳含义之一,因此重复相同变量名的刺激很高。 But in principal, you aren't bound to use str again. 但原则上,您不必再次使用str。 Maybe the new context provides a better name: 也许新的上下文提供了更好的名称:
tr match {
case Test1 (bar) => println (bar)
}
The parameter name, whether 'str' or 'bar' is used to deconstruct the Ctor-call to Test1, and is binding, what fits, to the new name. 参数名称(无论是“ str”还是“ bar”)用于解构对Test1的Ctor调用,并且将适合的名称绑定到新名称。
Note, that in your example: 请注意,在您的示例中:
tr match {
case test1 @ Test1(str) =>
str = test1.str + "some another string"
}
If you happen to need to refer to the whole thing, the name tr
is in scope, so you might refer to it: 如果您碰巧需要引用整个内容,则名称tr
在范围内,因此您可以引用它:
tr match {
case Test1 (str) => dedodulute (tr)
}
You aren't obliged to use str
on the right hand side at all. 您完全没有义务在右侧使用str
。
Sometimes you even like to refer to the parameter of your case class on the left hand side of the case statement: 有时,您甚至希望在case语句的左侧引用您的case类的参数:
tr match {
case Test1 (s) if (s.startsWith ("f")) => println ("foo")
case Test1 (s) if (s.startsWith ("b")) => println ("bar")
case _ => println ("unknown")
}
You may even pick a single element from a list, but have to know it's position from left: 您甚至可以从列表中选择一个元素,但必须从左知道它的位置:
val l = List (4, 1, 3, 9)
l match {
case List (_, a, _*) => println ("2nd el is " + a)
case _ => println ("unknown")
}
You can't use 你不能用
case List (_*, a, _) => println ("2nd last el is " + a)
But you may use literal values, to tighten your match: 但是您可以使用文字值来加强匹配:
l match {
case List (3, a, _*) => println ("2nd el is " + a + "after 3")
case List (4, a, _*) => println ("2nd el is " + a + "after 4")
case _ => println ("unknown")
}
You can do something like this: 您可以执行以下操作:
sealed trait Tr
case class Test1(str: String) extends Tr
val tem = Test1 ("I am immutable!!")
val str = tem match {
case Test1 (str) => str + "But you can assign me to something else :)."
}
println(str)
Your last case looks almost what you need: 您的最后一种情况几乎满足您的需求:
tr match {
case test1: Test1 =>
val str = test1.str + "some another string"
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.