Rzutowanie i konwersje (F#)
W tym temacie opisano obsługę konwersje typu F#.
Typy arytmetyczny
F# przewiduje operatory konwersji arytmetyczne konwersje między różnych typów pierwotnych, takie jak między typu liczba całkowita i liczba zmiennoprzecinkowa .Operatory konwersji integralną i char zostały sprawdzone i niezaznaczone formularzy; operatory liczba zmiennoprzecinkowa i enum konwersji operator nie.Jej źródłem jest niesprawdzony formularze są zdefiniowane w Microsoft.FSharp.Core.Operators i zaznaczone formularze są zdefiniowane w Microsoft.FSharp.Core.Operators.Checked.Zaznaczone formularze Sprawdź, czy przepełnienie i generować wyjątek wykonania, jeśli otrzymana wartość przekracza limity typ docelowy.
Każdy z tych operatorów ma taką samą nazwę jak nazwa typu miejsca docelowego.Na przykład, w poniższy kod, w których typy są wyraźnie odnotowany, byte pojawia się dwa różne znaczenie.Pierwsze wystąpienie jest typu, a po drugie konwersji operator.
let x : int = 5
let b : byte = byte x
W poniższej tabeli przedstawiono operatory konwersji zdefiniowane w F#.
Operator |
Opis |
---|---|
byte |
Konwertuj na bajt, bez znaku typu 8-bitowych. |
sbyte |
Konwertuj na podpisane bajt. |
int16 |
Konwertuj na 16-bitowe podpisane liczba całkowita. |
uint16 |
Konwertuj na 16-bitowe niepodpisane liczba całkowita. |
int32, int |
Konwertuj do podpisanej 32-bitowa liczba całkowita. |
uint32 |
Konwertuj na niepodpisane 32-bitowa liczba całkowita. |
int64 |
Konwertuj na 64-bitowych podpisane liczba całkowita. |
uint64 |
Konwertuj na 64-bitowych niepodpisane liczba całkowita. |
nativeint |
Konwertuj na natywny liczba całkowita. |
unativeint |
Konwertuj na niepodpisane natywny liczba całkowita. |
float, double |
Konwertuj na 64-bitowa liczba podwójnej precyzji IEEE liczba zmiennoprzecinkowa . |
float32, single |
Konwertuj na 32-bitowe pojedynczej precyzji IEEE liczba zmiennoprzecinkowa liczbę. |
decimal |
Konwertuj na System.Decimal. |
char |
Konwertuj na System.Char, znak Unicode . |
enum |
Konwertuj na typem wyliczeniowym. |
Oprócz wbudowanych typów pierwotnych, można używać tych operatorów z typami, które implementują op_Explicit lub op_Implicit metody z odpowiednim podpisem.Na przykład int konwersji operator współpracuje z dowolnego typu, który zapewnia statycznymetoda op_Explicit , przyjmuje typu jako parametr i zwraca int. Jako specjalny wyjątek od ogólnej zasady, że metody nie można obciążać przez typ zwracany, można to zrobić op_Explicit i op_Implicit.
Typy wyliczeniowe
enum operator jest rodzajowy operator , który przyjmuje jedną wpisz parametr , który reprezentuje typ enum do konwertować . Gdy są konwertowane na typem wyliczeniowym, wnioskowanie o typie próbuje określić typ enum , który chcesz konwertować .W poniższym przykładzie zmienna col1 nie jest jawnie odnotowany, ale jego typ jest wywnioskować na podstawie badania równości później. W związku z tym, kompilator może wywnioskowanie konwertujesz do Color wyliczanie. Alternatywnie, można podać typu adnotacja, tak jak w col2 w następującym przykładzie.
type Color =
| Red = 1
| Green = 2
| Blue = 3
// The target type of the conversion is determined by type inference.
let col1 = enum 1
// The target type is supplied by a type annotation.
let col2 : Color = enum 2
do
if (col1 = Color.Red) then
printfn "Red"
Typ wyliczanie docelowych można określić również jawnie jako typ parametr, jak w poniższym kodzie:
let col3 = enum<Color> 3
Uwaga wyliczanie rzuca pracy tylko wtedy, gdy podstawowy typ wyliczanie jest zgodny z typem konwertowana.W poniższym kodzie, konwersja nie powiedzie się kompilować ze względu na niezgodność między int32 i uint32.
// Error: types are incompatible
let col4 : Color = enum 2u
Aby uzyskać więcej informacji, zobacz Wyliczenia (F#).
Rzutowanie typów obiektów
Konwersja między typami w hierarchii obiekt ma fundamentalne znaczenie dla obiekt-oriented programming.Istnieją dwa podstawowe typy konwersji: rzutowanie up (rzutowanie rozszerzające) i oddał w dół (downcasting).Rzutowanie w górę hierarchii oznacza rzutowanie odniesienia pochodnych obiekt do odwołania podstawowego obiekt .Jest gwarantowane, że takie cast pracy tak długo, jak klasa base znajduje się w hierarchii dziedziczenia z klasa pochodna.Rzutowanie w dół hierarchii, z odwołania podstawowego obiekt do odwołania pochodnych obiekt , powiedzie się tylko wtedy, gdy obiekt jest faktycznie wystąpienie typu właściwego miejsca przeznaczenia (uzyskane) lub typu pochodną typu miejsca docelowego.
F# stanowi podmiotów gospodarczych dla tych typów konwersji.:>Rzuca operator w górę hierarchii oraz :?> operator rzuca się w dół hierarchii.
Rzutowanie rozszerzające
W wielu obiekt-zorientowany języków Rzutowanie rozszerzające jest niejawne; F# zasady są nieco inne.Rzutowanie rozszerzające jest stosowane automatycznie, gdy przekazywać argumenty do metod typu obiekt .Jednakże dla funkcji let bound w moduł, rzutowanie rozszerzające nie jest automatyczne, chyba, że typ parametr jest zadeklarowany jako typ elastyczne.Aby uzyskać więcej informacji, zobacz Typy elastyczne (F#).
:> operator wykonuje statyczny oddanych, co oznacza, że sukces oddanych jest określane w czasie kompilować . Jeśli rzutowania, która korzysta z :> kompiluje się pomyślnie, jest prawidłowy cast i ma istniała błąd w czasie wykonywania.
Można również użyć upcast operator do wykonywania takich konwersji. Poniższe wyrażenie określa konwersji w górę hierarchii.
upcast expression
Gdy używany jest operatorrzutowany w górę, kompilator próbuje rozpoznać typ, którą konwertujesz z kontekst.Jeśli nie można określić typ docelowy jest kompilator , kompilator zgłosi błąd.
Downcasting
:?> operator wykonuje dynamiczne, oddanych, co oznacza, że sukces oddanych jest określana w czasie wykonywania. Który korzysta z :?> operator nie jest zaznaczone w czasie kompilować ; Jednak w czasie wykonywania, podejmowana jest próba do oddania do określonego typu.Jeśli obiekt jest zgodny z typem docelowym, Obsada powiedzie się.Jeśli obiekt nie jest zgodny z typem docelowym, środowisko wykonawcze wywołuje InvalidCastException.
Można również użyć downcast operator do wykonywania konwersji typu dynamicznego. Poniższe wyrażenie określa konwersji w dół hierarchii do typu, który wywnioskować na podstawie programu w kontekst.
downcast expression
Jak w przypadku rzutowany w górę operatorJeśli kompilator nie może rozpoznać typ konkretnej wartości docelowej od kontekst, zgłasza jest błąd.
Poniższy kod ilustruje użycie :> i :?> podmiotów gospodarczych.Kod pokazuje, że :?>używany jest operator najlepiej gdy zna konwersja powiedzie się, że, ponieważ jej wyrzuca InvalidCastException Jeśli konwersja nie powiedzie się. Jeśli nie wiesz, że konwersja kończy się pomyślnie, badania typu, który korzysta z match wyrażenie jest lepsze, ponieważ unika się obciążenie związane z generuje wyjątek.
type Base1() =
abstract member F : unit -> unit
default u.F() =
printfn "F Base1"
type Derived1() =
inherit Base1()
override u.F() =
printfn "F Derived1"
let d1 : Derived1 = Derived1()
// Upcast to Base1.
let base1 = d1 :> Base1
// This might throw an exception, unless
// you are sure that base1 is really a Derived1 object, as
// is the case here.
let derived1 = base1 :?> Derived1
// If you cannot be sure that b1 is a Derived1 object,
// use a type test, as follows:
let downcastBase1 (b1 : Base1) =
match b1 with
| :? Derived1 as derived1 -> derived1.F()
| _ -> ()
downcastBase1 base1
Ponieważ operatory rodzajowy downcast i upcast opierają się na wnioskowanie o typie w celu określenia typu argument i, w powyższym kodzie, można zamienić
let base1 = d1 :> Base1
z
base1 = upcast d1
W poprzednim kodzie typ argument i typy zwracane są Derived1 i Base1, odpowiednio.
Aby uzyskać więcej informacji na temat badań typu, zobacz Wyrażenia dopasowania (F#).