Ograniczenia (F#)
W tym temacie opisano ograniczenia, które można stosować jako standardowy typ parametrów określających wymagania dla argumentu Typ w typie podstawowym lub funkcji.
type-parameter-list when constraint1 [ and constraint2]
Uwagi
Istnieje kilka różnych ograniczeń, które można zastosować, aby ograniczyć typy, które mogą być używane w typie rodzajowym.Poniższej tabeli wymieniono i opisano te ograniczenia.
Ograniczenie |
Składnia |
Opis |
---|---|---|
Ograniczenie typu |
type-parameter: > type |
Podany typ musi być równa lub pochodnych z typem określonym lub, jeśli typ to interfejs, pod warunkiem typ musi implementować interfejs. |
Ograniczenia Null |
type-parameter: null |
Podany typ musi obsługiwać literał null.Dotyczy to wszystkich typów obiektów .NET, ale nie F# listy, spójnej kolekcji, funkcji, klasy, rekordu lub typy Unii. |
Jawne ograniczenie Członkowskie |
[(]type-parameteror ...or type-parameter)] : (member-signature) |
Co najmniej jeden z podanych argumentów typu musi mieć element członkowski, który ma określony podpis; nie przeznaczone do ogólnego przeznaczenia. |
Ograniczenie Konstruktor |
type-parameter: (nowe: -> Jednostka ") |
Podany typ musi mieć domyślnego konstruktora. |
Ograniczenie typu wartości |
: struct |
Podany typ musi być typem wartości .NET. |
Ograniczenie typu odwołania |
: nie struct |
Podany typ musi być typem odwołania .NET. |
Ograniczenie typu wyliczenie |
: enum<underlying-type> |
Podany typ musi być typem wyliczeniowym, która ma określony typ podstawowy; nie przeznaczone do ogólnego przeznaczenia. |
Ograniczenie delegata |
: delegate<tuple-parameter-type, return-type> |
Podany typ musi być typem obiektu delegowanego, który ma określonymi argumentami i zwraca wartość; nie przeznaczone do ogólnego przeznaczenia. |
Ograniczenia porównania |
: porównanie |
Podany typ musi obsługiwać porównania. |
Ograniczenie równości |
: równości |
Podany typ musi obsługiwać równości. |
Ograniczenie niezarządzane |
: niezarządzane |
Podany typ musi być typu niezarządzanego.Unmanaged types are either certain primitive types (sbyte, byte, char, nativeint, unativeint, float32, float, int16, uint16, int32, uint32, int64, uint64, or decimal), enumeration types, nativeptr<_>, or a non-generic structure whose fields are all unmanaged types. |
Musisz dodać ograniczenie, gdy kod musi użyć funkcji, która jest dostępna na typ ograniczenia, ale nie znajduje się na typy w ogóle.Na przykład jeśli używasz ograniczenia typu, aby określić typ klasy, można użyć jednej z metod tej klasy w funkcji rodzajowy lub typu.
Określające ograniczenia są czasem potrzebne podczas pisania parametrów typu jawnie, ponieważ bez ograniczeń, kompilator nie ma możliwości sprawdzenia, że funkcje, które są używane będzie dostępny dla dowolnego typu, który może być dostarczone w czasie wykonywania dla parametru typu.
Najczęściej ograniczeń, których używasz w kodzie F# są ograniczenia typu, które określają podstawowych klas lub interfejsów.Inne ograniczenia albo są używane przez bibliotekę F# do implementowania pewne funkcje, takie jak ograniczenie jawnym Członkowskim, który jest używany do zaimplementowania przeciążanie operatorów arytmetycznych, lub są dostarczane, głównie, ponieważ język F# obsługuje kompletny zbiór ograniczeń, który jest obsługiwany przez aparat plików wykonywalnych języka wspólnego.
W trakcie wnioskowanie typu niektóre ograniczenia mają być automatycznie tworzone automatycznie przez kompilator.Na przykład, jeśli korzystasz z + operatora w funkcji kompilator ustala ograniczeniem jawnym Członkowskim na typy zmiennych, które są używane w wyrażeniu.
Poniższy kod ilustruje deklaracje pewne ograniczenia.
// Base Type Constraint
type Class1<'T when 'T :> System.Exception> =
class end
// Interface Type Constraint
type Class2<'T when 'T :> System.IComparable> =
class end
// Null constraint
type Class3<'T when 'T : null> =
class end
// Member constraint with static member
type Class4<'T when 'T : (static member staticMethod1 : unit -> 'T) > =
class end
// Member constraint with instance member
type Class5<'T when 'T : (member Method1 : 'T -> int)> =
class end
// Member constraint with property
type Class6<'T when 'T : (member Property1 : int)> =
class end
// Constructor constraint
type Class7<'T when 'T : (new : unit -> 'T)>() =
member val Field = new 'T()
// Reference type constraint
type Class8<'T when 'T : not struct> =
class end
// Enumeration constraint with underlying value specified
type Class9<'T when 'T : enum<uint32>> =
class end
// 'T must implement IComparable, or be an array type with comparable
// elements, or be System.IntPtr or System.UIntPtr. Also, 'T must not have
// the NoComparison attribute.
type Class10<'T when 'T : comparison> =
class end
// 'T must support equality. This is true for any type that does not
// have the NoEquality attribute.
type Class11<'T when 'T : equality> =
class end
type Class12<'T when 'T : delegate<obj * System.EventArgs, unit>> =
class end
type Class13<'T when 'T : unmanaged> =
class end
// Member constraints with two type parameters
// Most often used with static type parameters in inline functions
let inline add(value1 : ^T when ^T : (static member (+) : ^T * ^T -> ^T), value2: ^T) =
value1 + value2
// ^T and ^U must support operator +
let inline heterogenousAdd(value1 : ^T when (^T or ^U) : (static member (+) : ^T * ^U -> ^T), value2 : ^U) =
value1 + value2
// If there are multiple constraints, use the and keyword to separate them.
type Class14<'T,'U when 'T : equality and 'U : equality> =
class end