다음을 통해 공유


목록 패턴

메모

이 문서는 기능 사양입니다. 사양은 기능의 디자인 문서 역할을 합니다. 여기에는 기능 디자인 및 개발 중에 필요한 정보와 함께 제안된 사양 변경 내용이 포함됩니다. 이러한 문서는 제안된 사양 변경이 완료되고 현재 ECMA 사양에 통합될 때까지 게시됩니다.

기능 사양과 완료된 구현 간에 약간의 불일치가 있을 수 있습니다. 그러한 차이는 언어 디자인 모임(LDM)관련 노트에서 포착됩니다.

사양문서에서 기능 사양서를 C# 언어 표준으로 채택하는 과정에 대해 더 알아볼 수 있습니다.

챔피언 이슈: https://github.com/dotnet/csharplang/issues/3435

요약

배열 또는 목록을 패턴 시퀀스와 일치시킬 수 있습니다. 예를 들어 array is [1, 2, 3] 각각 1, 2, 3의 길이 3의 정수 배열을 해당 요소로 일치시킬 수 있습니다.

상세 디자인

패턴 구문은 다음과 같이 수정됩니다.

list_pattern_clause
  : '[' (pattern (',' pattern)* ','?)? ']'
  ;

list_pattern
  : list_pattern_clause simple_designation?
  ;

slice_pattern
  : '..' pattern?
  ;

primary_pattern
  : list_pattern
  | slice_pattern
  | // all of the pattern forms previously defined
  ;

두 가지 새로운 패턴이 있습니다.

  • list_pattern 요소를 일치시킬 때 사용됩니다.
  • slice_patternlist_pattern_clause에서 한 번만 직접 허용되며, 0개 이상의 요소를 폐기합니다.

패턴 호환성

list_pattern개수형인덱스형인 모든 유형과 호환됩니다. 액세스 가능한 인덱서는 Index을 인수로 받거나 단일 int 매개변수를 사용하는 인덱서가 있어야 합니다. 두 인덱서가 모두 있는 경우 전자가 선호됩니다.

하위 slice_pattern개수조각화 가능한 모든 형식과 호환됩니다. Range 인수로 사용하는 액세스 가능한 인덱서 또는 두 개의 int 매개 변수가 있는 액세스 가능한 Slice 메서드가 있습니다. 둘 다 있는 경우 전자가 선호됩니다.

하위 패턴이 없는 slice_patternlist_pattern과 호환되는 모든 형식과 호환됩니다.

이 규칙 집합은 범위 인덱서 패턴파생됩니다.

포괄성 검사

포괄성 검사는 위치 패턴과 마찬가지로 작동하며, ITuple에 해당하는 하위 패턴은 위치에 따라 일치하고, 길이 테스트를 위한 추가 노드로 보강됩니다.

예를 들어 다음 코드는 두 패턴이 동일한 DAG를 생성하기 때문에 오류를 생성합니다.

case [_, .., 1]: // expr.Length is >= 2 && expr[^1] is 1
case [.., _, 1]: // expr.Length is >= 2 && expr[^1] is 1

다르게

case [_, 1, ..]: // expr.Length is >= 2 && expr[1] is 1
case [.., 1, _]: // expr.Length is >= 2 && expr[^2] is 1

런타임에 하위 패턴이 일치하는 순서는 명시되지 않으며, 실패한 일치가 모든 하위 패턴과 일치하려고 시도하지 않을 수 있습니다.

특정 길이가 지정된 경우 두 하위 페이지가 동일한 요소를 참조할 수 있습니다. 이 경우 이 값에 대한 테스트가 의사 결정 DAG에 삽입됩니다.

  • 예를 들어, [_, >0, ..] or [.., <=0, _]이(가) length >= 2 && ([1] > 0 || length == 3 || [^2] <= 0)로 바뀌고, 길이 값 3은 다른 테스트를 의미합니다.
  • 길이 값이 3인 경우, [_, >0, ..] and [.., <=0, _]length >= 2 && [1] > 0 && length != 3 && [^2] <= 0로 변환되어 다른 테스트가 허용되지 않습니다.

따라서 런타임에 두 번째 사례에서 동일한 요소와 일치하기 때문에 case [.., p]: case [p]: 같은 오류가 발생합니다.

조각 하위 페이지가 목록 또는 길이 값과 일치하면 하위 페이지가 포함된 목록의 직접 하위 페이지인 것처럼 처리됩니다. 예를 들어 [..[1, 2, 3]][1, 2, 3]형식의 패턴을 포함합니다.

사용 중인 멤버에 대해 다음과 같은 가정이 수행됩니다.

  • 형식 개수 만드는 속성은 형식이 인덱싱 가능한 경우에만 항상 음수가 아닌 값을 반환하는 것으로 간주됩니다. 예를 들어 패턴 { Length: -1 } 배열과 일치할 수 없습니다.
  • 형식 로 조각화할 수 있도록 해주는 멤버는 적절히 동작하는 것으로 간주됩니다. 즉, 반환 값은 null이 아니며, 포함된 목록의 올바른 하위 조각입니다.

위의 가정 중 어느 것이라도 유지되지 않는 경우 패턴 일치 작업의 동작은 정의되지 않습니다.

낮추는

양식 expr is [1, 2, 3] 패턴은 다음 코드와 동일합니다.

expr.Length is 3
&& expr[new Index(0, fromEnd: false)] is 1
&& expr[new Index(1, fromEnd: false)] is 2
&& expr[new Index(2, fromEnd: false)] is 3

slice_pattern는 적절한 무시처럼 작동합니다. 즉, 해당 패턴에 대해서는 테스트가 수행되지 않으며, 오직 길이 및 인덱서와 같은 다른 노드에만 영향을 미칩니다. 예를 들어 양식 expr is [1, .. var s, 3] 패턴은 다음 코드와 동일합니다(명시적 IndexRange 지원을 통해 호환되는 경우).

expr.Length is >= 2
&& expr[new Index(0, fromEnd: false)] is 1
&& expr[new Range(new Index(1, fromEnd: false), new Index(1, fromEnd: true))] is var s
&& expr[new Index(1, fromEnd: true)] is 3

slice_pattern 대한 입력 형식 두 가지 예외를 제외하고 기본 this[Range] 또는 Slice 메서드의 반환 형식입니다. string 배열의 경우 string.SubstringRuntimeHelpers.GetSubArray 각각 사용됩니다.

해결되지 않은 질문

  1. 다차원 배열을 지원해야 하나요? (대답 [LDM 2021-05-26]: 지원되지 않습니다. 일반적인 MD 배열 중심 릴리스를 만들려면 목록 패턴뿐만 아니라 현재 부족한 모든 영역을 다시 확인하려고 합니다.)
  2. ..에 따라 slice_pattern에서 일반적인 패턴을 받아들여야 하나요? (대답 [LDM 2021-05-26]: 예, 조각 후에 모든 패턴이 허용됩니다.)
  3. 이 정의에 따르면 [..]expr.Length >= 0에 대한 패턴 테스트를 수행합니다. Length 항상 음수가 아닌 것으로 가정하여 이러한 테스트를 생략해야 하나요? (답변 [LDM 2021-05-26]: [..] 길이 검사를 내보내지 않음)