Это зависит от того, какой тип сопоставления вы имеете в виду - это довольно мощная конструкция, и ее можно использовать самыми разными способами. Однако я попытаюсь объяснить, как сопоставление с образцом работает со списками. Вы можете написать, например, эти шаблоны:
match l with
| [1; 2; 3] -> // specific list of 3 elements
| 1::rest -> // list starting with 1 followed by more elements
| x::xs -> // non-empty list with element 'x' followed by a list
| [] -> // empty list (no elements)
Список F # на самом деле является дискриминационным объединением, содержащим два случая: []
представляет пустой список или x::xs
представляет список с первым элементом x
, за которым следуют некоторые другие элементы. В C # это может быть представлено так:
// Represents any list
abstract class List<T> { }
// Case '[]' representing an empty list
class EmptyList<T> : List<T> { }
// Case 'x::xs' representing list with element followed by other list
class ConsList<T> : List<T> {
public T Value { get; set; }
public List<T> Rest { get; set; }
}
Шаблоны, приведенные выше, будут скомпилированы следующим образом (для упрощения я использую псевдокод):
if (l is ConsList) && (l.Value == 1) &&
(l.Rest is ConsList) && (l.Rest.Value == 2) &&
(l.Rest.Rest is ConsList) && (l.Rest.Rest.Value == 3) &&
(l.Rest.Rest.Rest is EmptyList) then
// specific list of 3 elements
else if (l is ConsList) && (l.Value == 1) then
var rest = l.Rest;
// list starting with 1 followed by more elements
else if (l is ConsList) then
var x = l.Value, xs = l.Rest;
// non-empty list with element 'x' followed by a list
else if (l is EmptyList) then
// empty list (no elements)
Как видите, в этом нет зацикливания. При обработке списков в F # вы должны использовать рекурсию для реализации цикла, но сопоставление с образцом используется для отдельных элементов (ConsList
), которые вместе составляют весь список.
Сопоставление с образцом в списках - это особый случай дискриминируемого объединения , который обсуждается sepp2k . Существуют и другие конструкции, которые могут появляться при сопоставлении с образцом, но по сути все они компилируются с использованием некоторого (сложного) оператора if
.