스칼라의 패턴 매칭 시스템에서 비교 연산자 사용


148

스칼라의 패턴 매칭 시스템을 사용하여 비교할 수 있습니까? 예를 들면 다음과 같습니다.

a match {
    case 10 => println("ten")
    case _ > 10 => println("greater than ten")
    case _ => println("less than ten")
}

두 번째 사례 진술은 불법이지만 "a가보다 클 때"를 지정할 수 있습니다.


1
이것은 또한 함수가 참인지 평가하는 데 사용될 수 있습니다. 예 :case x if x.size > 2 => ...
tstenner

2
중요한 것은 => 연산자의 왼쪽에있는 "패턴"이 실제로 "패턴"이라는 것입니다. 첫 번째 표현식에서 10은 정수 리터럴이 아닙니다. 따라서 왼쪽에서> check 또는 say function application isOdd (_)와 같은 작업을 수행 할 수 없습니다.
Ustaman Sangat

답변:


292

if패턴 뒤에 가드, 즉 부울 식을 추가 할 수 있습니다 .

a match {
    case 10 => println("ten")
    case x if x > 10 => println("greater than ten")
    case _ => println("less than ten")
}

편집 :이 이상 피상적 퍼팅 다릅니다하는 것으로 if 이후=>패턴이 있기 때문에 하지 않습니다 가드 사실이 아닌 경우 일치합니다.


3
벤, 좋은 대답은 실제로 패턴 가드의 중요성을 보여줍니다.
JeffV

32

술어를 일치 절에 통합하는 방법을 묻는 질문의 정신에 대한 비 응답으로,이 경우 술어는 match:

def assess(n: Int) {
  println(
    n compare 10 match {
      case 0 => "ten"
      case 1 => "greater than ten"
      case -1 => "less than ten"
    })
}

이제 문서는scala.math.Ordering.compare(T, T) 동일하지 않은 결과가 0 보다 크 거나 작을 것이라는 약속 만합니다 . Java Comparable#compareTo(T)는 Scala와 유사하게 지정됩니다. 스칼라의 현재 구현 에서와 같이 각각 양수 및 음수 값에 1과 -1을 사용하는 것이 일반적 이지만, 구현 이 아래에서 변경 될 위험이 없으면 그러한 가정을 할 수 없습니다.


5
이것을 실제 솔루션으로 제안하고 있는지 확실하지 않지만 문서화되지 않은 규칙이나 가정에 의존하는 것은 사용하지 않는 것이 좋습니다.
벤 제임스

1
바로 그거죠. 그래서 나는 "어떤 위험없이 그러한 가정을 할 수 없다"고 썼으며, "답이 아닌"것으로 대답했습니다. 이유 를 고려 compare()하고 compareTo()0, 1 및 -1을 공동 도메인으로 지정하지 않는 것이 흥미 롭습니다 .
seh

4
Math.signum는 (N 10 비교) 보장 것이다 -1, 0 또는 1
richj

1
오늘 아침에 내가 그 거의 확인 육년 문제의 구현 한 유형에서 다른 유형으로 이동하더라도, 내 원래의 대답을 작성 후, 스칼라는 여전히 반환 -1, 0, 또는 1의 기록 동작을 유지한다
SEH

2
유효한 답변이지만 개인적으로 나는 이것을 좋아하지 않습니다. 0,1 및 -1의 의미를 잊어 버리기가 너무 쉽습니다.
DanGordon

21

내 의견으로는 경비원을 추가하는 것보다 훨씬 읽기 쉬운 솔루션입니다.

(n compare 10).signum match {
    case -1 => "less than ten"
    case  0 => "ten"
    case  1 => "greater than ten"
}

노트:

  • Ordered.compare이 값이 이보다 작 으면 음의 정수를 반환하고, 크면 0같고 같으면 양수를 반환 합니다.
  • Int.signum압축의 출력 compare-1음의 수 (10 개 미만)의 경우, 1양극 (10 이상)에, 또는 0영 (10와 동일).

1

위의 답변과 아래 답변 모두 원래 질문에 완벽하게 답변하지만 일부 추가 정보는 https://docs.scala-lang.org/tour/pattern-matching.html 설명서에서 찾을 수 있지만 내 경우에는 맞지 않습니다. 그러나이 stackoverflow 답변은 Google의 첫 번째 제안이므로 위 질문의 모퉁이 인 답변을 게시하고 싶습니다.
내 질문은 :

  • 함수의 인수와 일치 식에서 가드를 사용하는 방법은 무엇입니까?

어떤 말로 표현할 수 있습니까?

  • 함수의 인수와 일치하는 식에서 if 문을 사용하는 방법은 무엇입니까?

대답은 아래 코드 예입니다.

    def drop[A](l: List[A], n: Int): List[A] = l match {
      case Nil => sys.error("drop on empty list")
      case xs if n <= 0 => xs
      case _ :: xs => drop(xs, n-1)
    }

scala fiddle에 링크 : https://scalafiddle.io/sf/G37THif/2 보시 다시피 case xs if n <= 0 => xs명령문은 guard (if) 문과 함께 n (함수 인수)을 사용할 수 있습니다.

나는 이것이 나와 같은 누군가를 돕기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.