제약 조건(F#)
이 항목에서는 제네릭 형식이나 함수의 형식 인수에 필요한 요구 사항을 지정하기 위해 제네릭 형식 매개 변수에 적용할 수 있는 제약 조건을 설명합니다.
type-parameter-list when constraint1 [ and constraint2]
설명
제네릭 형식에 사용 가능한 형식을 제한하기 위해 적용할 수 있는 제약 조건에는 여러 가지가 있습니다.다음 표에서는 그와 같은 제약 조건의 목록을 제공하고 각 제약 조건을 간략하게 설명합니다.
제약 조건 |
구문 |
설명 |
---|---|---|
형식 제약 조건 |
type-parameter :> type |
제공된 형식이 지정된 형식 또는 그 파생 형식과 같아야 합니다. 형식이 인터페이스이면 제공된 형식을 통해 인터페이스를 구현해야 합니다. |
Null 제약 조건 |
type-parameter : null |
제공된 형식이 null 리터럴을 지원해야 합니다.여기에는 F# 목록, 튜플, 함수, 클래스, 레코드 및 공용 구조체 형식을 제외한 모든 .NET 개체 형식이 포함됩니다. |
명시적 멤버 제약 조건 |
[(]type-parameteror ...or type-parameter)] : (member-signature) |
제공된 형식 인수 중 적어도 하나 이상의 인수 멤버에 지정된 시그니처가 있어야 합니다. 이 제약 조건은 일반적인 용도로 사용되지는 않습니다. |
생성자 제약 조건 |
type-parameter : ( new : unit -> 'a ) |
제공된 형식에 기본 생성자가 있어야 합니다. |
값 형식 제약 조건 |
: struct |
제공된 형식이 .NET 값 형식이어야 합니다. |
참조 형식 제약 조건 |
: not struct |
제공된 형식이 .NET 참조 형식이어야 합니다. |
열거형 제약 조건 |
: enum<underlying-type> |
제공된 형식이 지정된 내부 형식을 갖는 열거된 형식이어야 합니다. 이 제약 조건은 일반적인 용도로 사용되지는 않습니다. |
대리자 제약 조건 |
: delegate<tuple-parameter-type, return-type> |
제공된 형식이 지정된 인수와 반환 값을 갖는 대리자 형식이어야 합니다. 이 제약 조건은 일반적인 용도로 사용되지는 않습니다. |
비교 제약 조건 |
: comparison |
제공된 형식이 비교를 지원해야 합니다. |
같음 제약 조건 |
: equality |
제공된 형식이 같음을 지원해야 합니다. |
비관리 제약 조건 |
: unmanaged |
제공된 형식이 관리되지 않는 형식이어야 합니다.관리되지 않는 형식으로는 특정 기본 형식(sbyte, byte, char, nativeint, unativeint, float32, float, int16, uint16, int32, uint32, int64, uint64, decimal), 열거형 형식, nativeptr<_> 또는 모든 해당 필드가 관리되지 않는 형식이며 제네릭이 아닌 구조체가 있습니다. |
일반적인 형식에 대해서는 사용할 수 없고 제약 조건 형식에 대해서만 사용할 수 있는 기능이 코드에 포함된 경우 제약 조건을 추가해야 합니다.예를 들어 클래스 형식을 지정하기 위해 형식 제약 조건을 사용하는 경우 제네릭 함수나 형식에 해당 클래스의 메서드 중 하나를 사용할 수 있습니다.
제약 조건이 없으면 런타임에 형식 매개 변수에 대해 제공될 수 있는 모든 형식과 관련하여 사용자가 의도하는 기능을 사용할 수 있는지 여부를 컴파일러에서 확인할 방법이 없으므로 형식 매개 변수를 명시적으로 작성할 때 제약 조건을 지정해야 할 경우가 있습니다.
F# 코드에서 가장 일반적으로 사용되는 제약 조건은 기본 클래스 또는 인터페이스를 지정하는 형식 제약 조건입니다.다른 제약 조건은 산술 연산자에 대한 연산자 오버로드를 구현하는 데 사용되는 명시적 멤버 제약 조건 같이 특정 기능을 구현할 목적으로 F# 라이브러리에 사용되는 것이거나 CLR(공용 언어 런타임)을 통해 지원되는 모든 제약 조건 집합을 F#에서도 지원할 목적으로 제공되는 것이 대부분입니다.
형식 유추 프로세스를 진행하는 동안 컴파일러를 통해 일부 제약 조건이 자동으로 유추됩니다.예를 들어 함수에 + 연산자를 사용하면 컴파일러에서는 식에 사용되는 변수 형식에 대한 명시적 멤버 제약 조건을 유추합니다.
일부 제약 조건이 선언을 다음 코드를 보여 줍니다.
// 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