2017-05-07 1 views
5

간단한 수학 토큰 화 프로그램을 작성하고 새로운 C# pattern matching 기능을 사용해보십시오. 내가 if-else if 체인을 사용하지 않고 조건에 의해 일치 싶어서 case var _을 사용하고패턴 일치 사례

public IEnumerable<IToken> Tokenize(string input) 
    { 
     const char decimalSeparator = '.'; 
     string inputWithoutSpaces = input.Replace(" ", string.Empty); 
     var numberBuffer = new StringBuilder(); 
     var letterBuffer = new StringBuilder(); 
     foreach (char c in inputWithoutSpaces) 
     { 
      switch (c) 
      { 
       case var _ when IsTerm(c, letterBuffer): 
        if (numberBuffer.Length > 0) 
        { 
         yield return EmptyNumberBufferAsLiteral(numberBuffer); 
         yield return new Operator('*'); 
        } 
        letterBuffer.Append(c); 
        break; 
       case decimalSeparator: 
       case var _ when IsDigit(c): 
        numberBuffer.Append(c); 
        break; 
       case var _ when IsOperator(c): 
        if (numberBuffer.Length > 0) 
        { 
         yield return EmptyNumberBufferAsLiteral(numberBuffer); 
        } 
        if (letterBuffer.Length > 0) 
        { 
         yield return EmptyLetterBufferAsTerm(letterBuffer); 
        } 
        yield return new Operator(c); 
        break; 
      } 
     } 
     if (numberBuffer.Length > 0) 
     { 
      yield return EmptyNumberBufferAsLiteral(numberBuffer); 
     } 
     if (letterBuffer.Length > 0) 
     { 
      yield return EmptyLetterBufferAsTerm(letterBuffer); 
     } 
    } 

,하지만 난 var variableName를 지정하지 않고 case when을 쓸 수 없습니다 해요 :

토큰 화는 매우 간단합니다.

이러한 작업을 수행하는 멋진 방법이 있습니까? 아니면 이런 일을하는 것이 좋습니다.

+1

스위치 문에서 상수를 사용하는 요구 사항을 해결하기 위해 일종의 악용 패턴을 사용하기 때문에 진정한 방법은 없습니다. 또한, 당신의 논리가 아마도 맞는/if/else 문처럼 어쨌든 더 잘 읽는다고 생각합니다. – DavidG

+1

@DavidG 반대로, 토큰 화기 및 파서를 훨씬 쉽게 구현할 수있는 활성 패턴과 비슷합니다. C# 7의 패턴 매칭은 몇 가지 중요한 기능을 빠뜨린다. 활성 패턴 중 하나입니다. 그래도 철저한 매칭에 우선 순위를 두어야 겠어. –

+0

@PanagiotisKanavos 예,하지만 지금은 언어에서 사용할 수있는 것에 대해 이야기하고 있습니다. 앞으로 C#으로 들어가는 패턴 매칭을 훨씬 더 많이 보게 될 것이라고 확신합니다. (주로 F #로 추측합니다.) – DavidG

답변

2

일반적으로 활성 패턴이라고하는 것을 사용하여 이와 같이 패턴 일치를 수행하는 "멋진"방법이 있습니다. C#에서는 (아직) 활성 패턴을 지원하지 않지만 see this answer for an example of what they might look like if/when implemented을 지원합니다. 당신은 C#을 please upvote it on the csharplang github repo의 이후 버전에서는이 기능을보고 싶은 경우

switch (c) 
{ 
    case Term(letterBuffer): 
     ... 
     break; 
    case decimalSeparator: 
    case Digit(): 
     ... 
     break; 
    case Operator(): 
     ... 
     break; 
} 

:

그래서 활성 패턴을 사용하여 코드가 뭔가를 찾고 끝낼 것입니다.

그 동안 다른 사람들이 말한대로 if 진술을 사용하거나 제한없이 경비원을 사용할 때만 제한적으로 사용합니다. 당신은 정말로 선호하는 스타일의 문제 일뿐입니다.

+0

"놓친"사례를 방지하기 위해 먼저 구현 된 철저한 일치를 보았습니다. –

+1

@PanagiotisKanavos가 완전히 동의합니다. 불행히도 우리는 적절한 패턴 일치가 다른 OO 관련 기능들을 선호하여 뒤로 밀려나는 것을 보게 될 것이라고 생각합니다. 따라서 Op의 의사 활성 패턴은 당분간 할 길입니다. –