목록 이외의 시퀀스에 대한 스칼라 패턴 일치
List 내의 각 요소에서 재귀 적으로 작동하는 다음 코드가 있습니다.
def doMatch(list: List[Int]): Unit = list match {
case last :: Nil => println("Final element.")
case head :: tail => println("Recursing..."); doMatch(tail)
}
이제이 기능이 filter () 및 foreach ()를 통해 사용 가능하다는 것을 무시하면 잘 작동합니다. 그러나 Seq [Int] 를 받아들이도록 변경하려고하면 문제가 발생합니다.
- Seq에는 ::가 없지만 + :가 있습니다. 제가 이해하는 바와 같이 기본적으로 동일한 것입니다. 그러나 head + : tail에서 일치 시키려고하면 컴파일러가 'error : not found : value + :'라고 불평합니다.
- Nil은 List에만 해당되며 무엇으로 대체해야할지 모르겠습니다. 이전 문제를지나 치면 Seq ()를 시도해 보겠습니다.
작동하지 않는 것을 제외하고 코드가 어떻게 보일 것이라고 생각하는지는 다음과 같습니다.
def doMatch(seq: Seq[Int]): Unit = seq match {
case last +: Seq() => println("Final element.")
case head +: tail => println("Recursing..."); doMatch(tail)
}
편집 : 너무 많은 좋은 답변! agilesteel의 대답은 ::가 내 예제에서 연산자가 아니라 케이스 클래스이므로 차이가 있다는 것을 언급 한 첫 번째 사람 이었기 때문입니다.
::
Scala 에는 두 가지 (단점으로 발음 됨)가 있습니다. 하나는에 정의 된 연산자 class List
이고 다른 하나는 머리와 꼬리가 특징 인 비어 있지 않은 목록을 나타내는 클래스 (의 하위 클래스 List
)입니다.
head :: tail
에서 구문 상 수정 된 생성자 패턴입니다 ::(head, tail)
.
::
케이스 클래스입니다. 이는 이에 대해 정의 된 추출기 오브젝트가 있음을 의미합니다.
일종의 속임수이지만 여기에 있습니다.
def doMatch(seq: Seq[Int]): Unit = seq match {
case Seq(x) => println("Final element " + x)
case Seq(x, xs@_*) => println("Recursing..." + x); doMatch(xs)
}
왜 xs*
작동 하지 않는지 묻지 마세요 ...
2012 년 3 월의 ides 현재 2.10 이상에서 작동합니다.
def doMatch(seq: Seq[Int]): Unit = seq match {
case last +: Seq() => println("Final element.")
case head +: tail => println("Recursing..."); doMatch(tail)
} //> doMatch: (seq: Seq[Int])Unit
doMatch(List(1, 2)) //> Recursing...
//| Final element.
더 일반적으로, 두 개의 서로 다른 헤드 / 테일 및 초기화 / 마지막 분해는 객체 미러링 APPEND / 앞에 추가 추가되었다 Seq
에서 SeqExtractors :
List(1, 2) match { case init :+ last => last } //> res0: Int = 2
List(1, 2) match { case head +: tail => tail } //> res1: List[Int] = List(2)
Vector(1, 2) match { case init :+ last => last } //> res2: Int = 2
Vector(1, 2) match { case head +: tail => tail } //> res3: scala.collection.immutable.Vector[Int] = Vector(2)
실제로 +:
원하는 것을 정확히 수행 하기 위해 객체를 정의 할 수 있습니다 .
object +: {
def unapply[T](s: Seq[T]) =
if(s.nonEmpty)
Some(s.head, s.tail)
else
None
}
scala> val h +: t = Seq(1,2,3)
h: Int = 1
t: Seq[Int] = List(2, 3)
그러면 코드가 예상대로 정확하게 작동합니다.
이것은 패턴 매칭에 사용될 때 h +: t
와 동일하기 때문에 작동합니다 +:(h,t)
.
표준 라이브러리에서 임의의 시퀀스에 대한 패턴 일치 지원이 없다고 생각합니다. 하지만 패턴 매칭없이 할 수 있습니다.
def doMatch(seq: Seq[Int]) {
if (seq.size == 1) println("final element " + seq(0)) else {
println("recursing")
doMatch(seq.tail)
}
}
doMatch(1 to 10)
하지만 자체 추출기 개체를 정의 할 수 있습니다. 참조 http://www.scala-lang.org/node/112를
object SEQ {
def unapply[A](s:Seq[A]):Option[(A, Seq[A])] = {
if (s.size == 0) None else {
Some((s.head, s.tail))
}
}
}
def doMatch(seq: Seq[Int]) {
seq match {
case SEQ(head, Seq()) => println("final")
case SEQ(head, tail) => {
println("recursing")
doMatch(tail)
}
}
}
Seq에서 List 로의 간단한 변환은 작업을 수행합니다.
def doMatch (list: List[Int]): Unit = list match {
case last :: Nil => println ("Final element.")
case head :: tail => println ("Recursing..."); doMatch (tail)
case Nil => println ("only seen for empty lists")
}
def doMatchSeq (seq: Seq[Int]) : Unit = doMatch (seq.toList)
doMatch (List(3, 4, 5))
doMatchSeq (3 to 5)
ReferenceURL : https://stackoverflow.com/questions/6807540/scala-pattern-matching-on-sequences-other-than-lists
'programing' 카테고리의 다른 글
MSMQ (Microsoft Message Queuing) 란 무엇입니까? (0) | 2021.01.17 |
---|---|
div에서 innerHTML 제거 (0) | 2021.01.17 |
사전 컴파일 된 자산이 개발 모드에서 제공되는 것을 방지하는 방법은 무엇입니까? (0) | 2021.01.17 |
Python에서 "홈 디렉토리"를 찾으십니까? (0) | 2021.01.17 |
MySQL-기존 데이터를 손상시키지 않고 데이터베이스에서 기존 열의 varchar 크기를 늘리는 방법은 무엇입니까? (0) | 2021.01.17 |