模式匹配案例 when
Pattern matching case when
我编写了简单的数学分词器并尝试使用新的 C# pattern matching
功能。
分词器非常简单:
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);
}
}
我正在使用 case var _
,因为我想在不使用 if-else if
链的情况下按条件进行匹配,但是如果不指定 var variableName
,我将无法编写 case when
。
有没有什么奇特的方法来执行这样的操作?或者推荐的方法来做这些事情?
有一种 "fancy" 方法可以像这样使用通常称为活动模式的模式进行模式匹配。 C# 不(还)支持活动模式,但是 .
因此使用活动模式,您的代码最终会看起来像:
switch (c)
{
case Term(letterBuffer):
...
break;
case decimalSeparator:
case Digit():
...
break;
case Operator():
...
break;
}
如果您希望在未来的 C# 版本中看到此功能,please upvote it on the csharplang github repo。
与此同时,您只能在坚持使用 if
语句(如其他人所说)或使用 when 守卫之间进行选择。至于你喜欢哪一种,只是喜欢的风格而已。
我编写了简单的数学分词器并尝试使用新的 C# pattern matching
功能。
分词器非常简单:
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);
}
}
我正在使用 case var _
,因为我想在不使用 if-else if
链的情况下按条件进行匹配,但是如果不指定 var variableName
,我将无法编写 case when
。
有没有什么奇特的方法来执行这样的操作?或者推荐的方法来做这些事情?
有一种 "fancy" 方法可以像这样使用通常称为活动模式的模式进行模式匹配。 C# 不(还)支持活动模式,但是
因此使用活动模式,您的代码最终会看起来像:
switch (c)
{
case Term(letterBuffer):
...
break;
case decimalSeparator:
case Digit():
...
break;
case Operator():
...
break;
}
如果您希望在未来的 C# 版本中看到此功能,please upvote it on the csharplang github repo。
与此同时,您只能在坚持使用 if
语句(如其他人所说)或使用 when 守卫之间进行选择。至于你喜欢哪一种,只是喜欢的风格而已。