Wnioskowanie o typie
W tym temacie opisano, jak kompilator języka F# wywnioskuje typy wartości, zmiennych, parametrów i zwracanych wartości.
Wnioskowanie typów w ogóle
Chodzi o to, że nie trzeba określać typów konstrukcji języka F#, z wyjątkiem sytuacji, gdy kompilator nie może wywnioskować typu. Pominięcie jawnych informacji o typie nie oznacza, że język F# jest dynamicznie wpisanym językiem lub że wartości w języku F# są słabo wpisywane. F# to statycznie typizowanego języka, co oznacza, że kompilator deduuje dokładny typ każdej konstrukcji podczas kompilacji. Jeśli nie ma wystarczającej ilości informacji dla kompilatora w celu wyłudzenia typów każdej konstrukcji, należy podać dodatkowe informacje o typie, zazwyczaj dodając jawne adnotacje typu gdzieś w kodzie.
Wnioskowanie typów parametrów i zwracanych
Na liście parametrów nie trzeba określać typu każdego parametru. A jednak język F# jest statycznie wpisanym językiem, dlatego każda wartość i wyrażenie mają określony typ w czasie kompilacji. W przypadku tych typów, które nie są jawnie określone, kompilator wywnioskuje typ na podstawie kontekstu. Jeśli typ nie zostanie określony w inny sposób, zostanie on wywnioskowany jako ogólny. Jeśli kod używa wartości w spójny sposób, w taki sposób, że nie ma jednego wywnioskowanego typu, który spełnia wszystkie zastosowania wartości, kompilator zgłasza błąd.
Zwracany typ funkcji jest określany przez typ ostatniego wyrażenia w funkcji.
Na przykład w poniższym kodzie typy parametrów a
i b
typ zwracany są wywnioskowane int
, ponieważ literał 100
ma typ int
.
let f a b = a + b + 100
Możesz wpływać na wnioskowanie typu, zmieniając literały. Jeśli element a zostanie dodany 100
przez dołączenie sufiksu u
, typy a
, b
i zwracana wartość zostaną wywnioskowane jako uint32
.uint32
Możesz również wpływać na wnioskowanie typu przy użyciu innych konstrukcji, które sugerują ograniczenia dotyczące typu, takich jak funkcje i metody, które działają tylko z określonym typem.
Ponadto można zastosować jawne adnotacje typu do parametrów funkcji lub metody lub zmiennych w wyrażeniach, jak pokazano w poniższych przykładach. Błędy powodują, że konflikty występują między różnymi ograniczeniami.
// Type annotations on a parameter.
let addu1 (x : uint32) y =
x + y
// Type annotations on an expression.
let addu2 x y =
(x : uint32) + y
Można również jawnie określić wartość zwracaną funkcji, podając adnotację typu po wszystkich parametrach.
let addu1 x y : uint32 =
x + y
Typowy przypadek, w którym adnotacja typu jest przydatna w parametrze, jest to, gdy parametr jest typem obiektu i chcesz użyć elementu członkowskiego.
let replace(str: string) =
str.Replace("A", "a")
Automatyczna generalizacja
Jeśli kod funkcji nie jest zależny od typu parametru, kompilator uzna parametr za ogólny. Jest to nazywane automatyczną uogólniania i może być zaawansowaną pomocą do pisania kodu ogólnego bez zwiększania złożoności.
Na przykład poniższa funkcja łączy dwa parametry dowolnego typu w krotkę.
let makeTuple a b = (a, b)
Typ jest wnioskowany jako
'a -> 'b -> 'a * 'b
Dodatkowe informacje
Wnioskowanie typu zostało szczegółowo opisane w specyfikacji języka F#.