반응형
스칼라의 여러 케이스 클래스 일치
일부 케이스 클래스에 대해 일치를 수행하고 있으며 동일한 방식으로 두 케이스를 처리하고 싶습니다. 이 같은:
abstract class Foo
case class A extends Foo
case class B(s:String) extends Foo
case class C(s:String) extends Foo
def matcher(l: Foo): String = {
l match {
case A() => "A"
case B(sb) | C(sc) => "B"
case _ => "default"
}
}
하지만 이렇게하면 오류가 발생합니다.
(fragment of test.scala):10: error: illegal variable in pattern alternative
case B(sb) | C(sc) => "B"
B와 C의 정의에서 매개 변수를 제거하여 작동하도록 할 수 있지만 매개 변수와 어떻게 일치시킬 수 있습니까?
String 매개 변수의 값에 신경 쓰지 않고 B와 C를 동일하게 취급하려는 것 같습니다.
def matcher(l: Foo): String = {
l match {
case A() => "A"
case B(_) | C(_) => "B"
case _ => "default"
}
}
매개 변수를 추출하고 동일한 코드 블록에서 처리해야하는 경우 다음을 수행 할 수 있습니다.
def matcher(l: Foo): String = {
l match {
case A() => "A"
case bOrC @ (B(_) | C(_)) => {
val s = bOrC.asInstanceOf[{def s: String}].s // ugly, ugly
"B(" + s + ")"
}
case _ => "default"
}
}
나는 그것을 방법으로 고려하는 것이 훨씬 깨끗하다고 생각하지만 :
def doB(s: String) = { "B(" + s + ")" }
def matcher(l: Foo): String = {
l match {
case A() => "A"
case B(s) => doB(s)
case C(s) => doB(s)
case _ => "default"
}
}
케이스 클래스간에 공통점이있는 경우 원하는 것을 달성하기 위해 내가 볼 수있는 몇 가지 방법이 있습니다. 첫 번째는 케이스 클래스가 공통성을 선언하는 특성을 확장하도록하는 것이고, 두 번째는 케이스 클래스를 확장 할 필요가없는 구조적 유형을 사용하는 것입니다.
object MuliCase {
abstract class Foo
case object A extends Foo
trait SupportsS {val s: String}
type Stype = Foo {val s: String}
case class B(s:String) extends Foo
case class C(s:String) extends Foo
case class D(s:String) extends Foo with SupportsS
case class E(s:String) extends Foo with SupportsS
def matcher1(l: Foo): String = {
l match {
case A => "A"
case s: Stype => println(s.s); "B"
case _ => "default"
}
}
def matcher2(l: Foo): String = {
l match {
case A => "A"
case s: SupportsS => println(s.s); "B"
case _ => "default"
}
}
def main(args: Array[String]) {
val a = A
val b = B("B's s value")
val c = C("C's s value")
println(matcher1(a))
println(matcher1(b))
println(matcher1(c))
val d = D("D's s value")
val e = E("E's s value")
println(matcher2(d))
println(matcher2(e))
}
}
구조적 유형 방법은 삭제에 대한 경고를 생성하며 현재로서는 제거 방법을 모르겠습니다.
글쎄요, 정말 말이되지 않죠? B와 C는 상호 배타적이므로 sb 또는 sc가 바인딩되지만 어느 쪽을 사용할지 알 수 없으므로 사용할 항목을 결정하려면 추가 선택 논리가 필요합니다 (옵션 [문자열]에 바인딩 된 경우 문자열). 따라서 이것에 대해 얻은 것은 없습니다.
l match {
case A() => "A"
case B(sb) => "B(" + sb + ")"
case C(sc) => "C(" + sc + ")"
case _ => "default"
}
아니면 이거:
l match {
case A() => "A"
case _: B => "B"
case _: C => "C"
case _ => "default"
}
참고 URL : https://stackoverflow.com/questions/1837754/match-multiple-cases-classes-in-scala
반응형
'Programming' 카테고리의 다른 글
혼란을 줄이는 것 외에 사용하지 않는 가져 오기를 Java에서 정리해야하는 이유가 있습니까? (0) | 2020.08.23 |
---|---|
CMake에서 미리 컴파일 된 헤더 사용 (0) | 2020.08.23 |
참조 된 프로젝트는 컴파일 시간에 "손실"됩니다. (0) | 2020.08.23 |
객체 직렬화 대신 Parcelable 사용의 이점 (0) | 2020.08.23 |
Hg 지점 폐쇄 (0) | 2020.08.23 |