Scala의 패턴 일치가 변수와 함께 작동하지 않는 이유는 무엇입니까?


113

다음 기능을 사용하십시오.

def fMatch(s: String) = {
    s match {
        case "a" => println("It was a")
        case _ => println("It was something else")
    }
}

이 패턴은 잘 어울립니다.

scala> fMatch("a")
It was a

scala> fMatch("b")
It was something else

내가 할 수있는 것은 다음과 같습니다.

def mMatch(s: String) = {
    val target: String = "a"
    s match {
        case target => println("It was" + target)
        case _ => println("It was something else")
        }
}

이로 인해 다음 오류가 발생합니다.

fMatch: (s: String)Unit
<console>:12: error: unreachable code
               case _ => println("It was something else")

타겟이 실제로 입력이 무엇이든 할당하고 싶은 이름이라고 생각하기 때문이라고 생각합니다. 두 가지 질문 :

  1. 왜 이런 행동입니까? 적절한 유형을 가진 범위에서 기존 변수를 찾아서 먼저 사용하고 아무것도 발견되지 않으면 대상을 패턴 일치 이름으로 취급 할 수 없습니까?

  2. 이에 대한 해결 방법이 있습니까? 변수에 대한 패턴 일치 방법이 있습니까? 궁극적으로 큰 if 문을 사용할 수 있지만 대소 문자 구분이 더 우아합니다.



1
이 질문, 코드 및 답변은 ​​Scala 2.12.x에서 구식이라고 생각합니다. 적용되는 버전이 질문의 일부로 언급되면 좋을 것입니다.
코니

답변:


217

당신이 찾고있는 것은 안정적인 식별자 입니다. Scala에서는 대문자로 시작하거나 백틱으로 둘러싸 야합니다.

이 두 가지 모두 문제에 대한 해결책이 될 것입니다.

def mMatch(s: String) = {
    val target: String = "a"
    s match {
        case `target` => println("It was" + target)
        case _ => println("It was something else")
    }
}

def mMatch2(s: String) = {
    val Target: String = "a"
    s match {
        case Target => println("It was" + Target)
        case _ => println("It was something else")
    }
}

둘러싸는 범위에 이미 존재하는 변수를 우연히 참조하지 않으려면 기본 동작이 소문자 패턴이 안정적인 식별자가 아닌 변수 인 것이 합리적이라고 생각합니다. 대문자로 시작하거나 백틱으로 시작하는 것을 볼 때만 주변 범위에서 비롯된다는 점을 인식해야합니다.


3
변수는 대문자로 시작하고 기호는 소문자로 시작하는 Erlang에서 비롯된 것입니다.
Emil Ivanov

11
공지 사항 target값 (이다 val), 그리고 변수를 ( var). 변수에서는 작동하지 않습니다.
Luigi Plinge 2011 년

대문자? FORTRAN의 그늘. 약해, 마틴, 약해.
Malvolio

13
@Emil 실제로 Scala에서 대문자로 표시된 식별자는 상수를 나타냅니다. 따라서 대문자 식별자에 대한 패턴 일치는 상수와 비교하는 것을 의미합니다. 그것은 심각하게 같은 물건에 도움이 Nil, 내가 내기 진짜 이유입니다.
Daniel C. Sobral

this패턴 일치를위한 안정적인 식별자로 사용할 수없는 것처럼 보이지만 유일한 방법은 case x if x == this =>. 아마도 구문상의 제한 일 것입니다. 그렇지 않으면 적어도 objects 내에서 의미 상 작동해야합니다 .
Nader Ghanbari
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.