상수 문자열의 패턴 일치 Span<char>
메모
이 문서는 기능 사양입니다. 사양은 기능의 디자인 문서 역할을 합니다. 여기에는 기능 디자인 및 개발 중에 필요한 정보와 함께 제안된 사양 변경 내용이 포함됩니다. 이러한 문서는 제안된 사양 변경이 완료되고 현재 ECMA 사양에 통합될 때까지 게시됩니다.
기능 사양과 완료된 구현 간에 약간의 불일치가 있을 수 있습니다. 해당 차이점들은 언어 디자인 회의(LDM) 관련노트에 기록되어 있습니다.
사양문서에서 C# 언어 표준에 '기능 사양서'를 채택하는 과정에 대해 더 자세히 알아볼 수 있습니다.
챔피언 이슈: https://github.com/dotnet/csharplang/issues/8640
요약
상수 문자열에서 Span<char>
과 ReadOnlySpan<char>
에 대한 패턴 일치를 허용합니다.
동기
성능의 경우 많은 시나리오에서 문자열보다 Span<char>
및 ReadOnlySpan<char>
사용하는 것이 좋습니다. 프레임워크는 ReadOnlySpan<char>
대신 string
사용할 수 있도록 많은 새 API를 추가했습니다.
문자열에 대한 일반적인 작업은 스위치를 사용하여 특정 값인지 테스트하는 것이며 컴파일러는 이러한 스위치를 최적화합니다. 그러나 현재는 스위치 및 최적화를 수동으로 구현하는 것 외에는 ReadOnlySpan<char>
에서 동일한 작업을 효율적으로 수행할 방법이 없습니다.
ReadOnlySpan<char>
의 채택을 장려하기 위해, 우리는 ReadOnlySpan<char>
와 같은 상수에 대해 string
패턴 매칭을 허용하여 스위치에서도 사용할 수 있습니다.
static bool Is123(ReadOnlySpan<char> s)
{
return s is "123";
}
static bool IsABC(Span<char> s)
{
return s switch { "ABC" => true, _ => false };
}
상세 디자인
다음과 같이 상수 패턴에 대한 사양을 변경합니다(굵게 표시된 부분이 제안된 추가입니다).
패턴 입력 값
e
및 변환된 값이P
인 상수 패턴v
이 주어진 경우
- e가 정수형 또는 열거형, 또는 그 nullable 형태를 가질 때, v가 정수형인 경우, 패턴
P
와 일치시킵니다. 그렇지 않으면- e
System.Span<char>
또는System.ReadOnlySpan<char>
형식이고 c 상수 문자열이고 c 상수 값이null
없는 경우System.MemoryExtensions.SequenceEqual<char>(e, System.MemoryExtensions.AsSpan(c))
true
반환하는 경우 패턴이 일치하는 것으로 간주됩니다.- 패턴
P
이 값 .
잘 알려진 멤버
System.Span<T>
및 System.ReadOnlySpan<T>
은 이름으로 일치해야 하며, ref struct
이어야 하고 corlib 외부에서 정의할 수 있습니다.
System.MemoryExtensions
는 이름에 의해 매칭되며 corlib 외부에서 정의할 수 있습니다.
System.MemoryExtensions.SequenceEqual
오버로드의 서명은 다음과 일치해야 합니다.
public static bool SequenceEqual<T>(System.Span<T>, System.ReadOnlySpan<T>)
public static bool SequenceEqual<T>(System.ReadOnlySpan<T>, System.ReadOnlySpan<T>)
System.MemoryExtensions.AsSpan
서명은 다음과 일치해야 합니다.
public static System.ReadOnlySpan<char> AsSpan(string)
선택적 매개 변수가 있는 메서드는 고려 사항에서 제외됩니다.
단점
없음
대안
없음
해결되지 않은 질문
매칭은
MemoryExtensions.SequenceEqual()
등과 독립하여 정의되어야 하나요?... 패턴은
e.Length == c.Length
의 모든 문자에 대해e[i] == c[i]
과e
이 적용되는 경우 일치하는 것으로 간주됩니다.권장 사항: 성능을 기준으로
MemoryExtensions.SequenceEqual()
측면에서 정의합니다.MemoryExtensions
누락된 경우 컴파일 오류를 보고합니다.(string)null
에 대한 매칭이 허용되어야 하나요?그렇다면
(string)null
이후""
가MemoryExtensions.AsSpan(null) == MemoryExtensions.AsSpan("")
을 포함해야 하나요?static bool IsEmpty(ReadOnlySpan<char> span) { return span switch { (string)null => true, // ok? "" => true, // error: unreachable? _ => false, }; }
권장 사항: 일정한 패턴
(string)null
을 오류로 간주해야 합니다.상수 패턴 일치에
Span<char>
또는ReadOnlySpan<char>
식 값의 런타임 형식 테스트가 포함되어야 하나요?static bool Is123<T>(Span<T> s) { return s is "123"; // test for Span<char>? } static bool IsABC<T>(Span<T> s) { return s is Span<char> and "ABC"; // ok? } static bool IsEmptyString<T>(T t) where T : ref struct { return t is ""; // test for ReadOnlySpan<char>, Span<char>, string? }
권장 사항: 상수 패턴에 대한 암시적 런타임 형식 테스트가 없습니다. (
IsABC<T>()
예제는 형식 테스트가 명시적이므로 허용됩니다.)이 권장 사항은 구현되지 않았습니다. 위의 모든 샘플은 컴파일러 오류를 생성합니다.
포함 관계는 상수 문자열 패턴, 목록 패턴 및
Length
속성 패턴을 고려해야 하나요?static int ToNum(ReadOnlySpan<char> s) { return s switch { { Length: 0 } => 0, "" => 1, // error: unreachable? ['A',..] => 2, "ABC" => 3, // error: unreachable? _ => 4, }; }
권장 사항: 식 값이
string
때 사용되는 것과 동일한 하위 가정 동작입니다.Length
을 일치하는 것으로 처리하는 것 외에는 상수 문자열, 목록 패턴,[..]
간의 포함 관계가 없음을 의미하나요?
디자인 회의
C# feature specifications