Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Сопоставление шаблонов
Заметка
Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Она включает предлагаемые изменения спецификации, а также информацию, необходимую во время дизайна и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию ECMA.
Может возникнуть некоторое несоответствие между спецификацией компонентов и завершенной реализацией. Эти различия зафиксированы в соответствующих заметках собраний по проектированию языка (LDM).
Дополнительные сведения о процессе внедрения спецификаций функций в стандарт языка C# см. в статье о спецификациях .
Вопрос чемпиона: https://github.com/dotnet/csharplang/issues/8640
Сводка
Разрешить совпадение шаблона для Span<char> и ReadOnlySpan<char> в константной строке.
Мотивация
Для производительности использование Span<char> и ReadOnlySpan<char> предпочтительнее по сравнению со строкой во многих сценариях. Платформа добавила множество новых API, которые позволяют использовать ReadOnlySpan<char> вместо string.
Распространенная операция со строками заключается в использовании переключателя для проверки того, является ли это определенное значение, и компилятор оптимизирует такой коммутатор. Однако в настоящее время нет возможности сделать то же самое на 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 имеет целочисленный тип или тип перечисления, или пустую форму одного из них, а v имеет целочисленный тип, шаблон
Pсоответствует значению e, если результат выраженияe == vравенtrue; иначе- Если e имеет тип
System.Span<char>илиSystem.ReadOnlySpan<char>, а c является константной строкой, а c не имеет константного значенияnull, то шаблон считается совпадающим, еслиSystem.MemoryExtensions.SequenceEqual<char>(e, System.MemoryExtensions.AsSpan(c))возвращаетtrue.- Шаблон
Pсоответствует значению e, еслиobject.Equals(e, v)возвращаетtrue.
Известные члены
System.Span<T> и System.ReadOnlySpan<T> совпадают по имени, должны быть ref structи могут быть определены вне corelib.
System.MemoryExtensions совпадает по имени и может быть определён вне corelib.
Сигнатура перегрузки 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