Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A statikusan feloldott típusparaméter olyan típusparaméter, amelyet a rendszer a fordítási időpontban a tényleges típusra cserél le a futási idő helyett.
Syntax
'type-parameter
Az F# 7.0-s verziójáig az alábbi szintaxist kellett használni
^type-parameter
Megjegyzések
Az F#-ban kétféle típusparaméter létezik. Az első típus a szabványos általános típusparaméter. Ezek egyenértékűek más .NET-nyelvek általános típusparaméterekkel. A másik típus statikusan oldható fel, és csak beágyazott függvényekben használható.
A statikusan feloldott típusparaméterek elsősorban a tagkorlátozásokkal együtt hasznosak, amelyek olyan megkötések, amelyek lehetővé teszik annak megadását, hogy egy típusargumentumnak egy adott taggal vagy taggal kell rendelkeznie a használathoz. Ezt a kényszert nem lehet normál általános típusparaméter használatával létrehozni.
Az alábbi táblázat a típusparaméterek két típusa közötti hasonlóságokat és különbségeket foglalja össze.
| Szolgáltatás | Általános | Statikusan feloldva |
|---|---|---|
| Megoldási idő | Lefutási idő | Fordítási idő |
| Tagkorlátozások | Tagkorlátozásokkal nem használható. | Tagkorlátozásokkal használható. |
| Kódgenerálás | A standard általános típusparaméterekkel rendelkező típus (vagy metódus) egyetlen általános típus vagy metódus létrehozását eredményezi. | A rendszer több típus- és metódus-példányt hoz létre, amelyek mindegyike szükséges. |
| Használat típusokkal | Típusok esetén használható. | Típusokon nem használható. |
| Használat beágyazott függvényekkel | A beágyazott függvények nem paraméterezhetők szabványos általános típusparaméterrel. Ha a bemenetek nem teljesen általánosak, az F#-fordító specializálja őket, vagy ha nincs lehetőség a specializálásra, hibaüzenetet ad. | A statikusan feloldott típusparaméterek nem használhatók beágyazott függvényeken vagy metódusokon. |
Számos F# alapvető kódtárfüggvény, különösen az operátorok statikusan feloldott típusparaméterekkel rendelkeznek. Ezek a függvények és operátorok beágyazottak, és hatékony kódgenerálást eredményeznek a numerikus számításokhoz.
A beágyazott metódusok és függvények, amelyek operátorokat használnak, vagy más, statikusan feloldott típusparaméterekkel rendelkező függvényeket használnak, maguk is használhatnak statikusan feloldott típusparamétereket. A típuskövetkezmények gyakran arra következtetnek, hogy az ilyen beágyazott függvények statikusan feloldott típusparaméterekkel rendelkeznek. Az alábbi példa egy operátordefiníciót mutat be, amely arra következtet, hogy statikusan feloldott típusparaméterrel rendelkezik.
let inline (+@) x y = x + x * y
// Call that uses int.
printfn "%d" (1 +@ 1)
// Call that uses float.
printfn "%f" (1.0 +@ 0.5)
A feloldott típus a (+@) mind a kettő (+)(*), mind pedig a típuskövetkezmények felhasználásán alapul, amelyek a statikusan feloldott típusparaméterekre vonatkozó tagkorlátozásokra következtetnek. A feloldott típus az F#-értelmezőben látható módon a következő.
'a -> 'c -> 'd
when ('a or 'b) : (static member ( + ) : 'a * 'b -> 'd) and
('a or 'c) : (static member ( * ) : 'a * 'c -> 'b)
A kimenet a következő.
2
1.500000
Az alábbi példa az SRTP-k használatát mutatja be metódusokkal és statikus módszerekkel:
type Record =
{ Number: int }
member this.Double() = { Number = this.Number * 2 }
static member Zero() = { Number = 0 }
let inline double<'a when 'a:(member Double: unit -> 'a)> (x: 'a) = x.Double()
let inline zero<'a when 'a:(static member Zero: unit -> 'a)> () = 'a.Zero()
let r: Record = zero ()
let doubleR = double r
Az F# 7.0-tól kezdve használhatja 'a.Zero() a kényszer megismétlése helyett, ahogy az alábbi példában is látható.
Az F# 4.1-től kezdve konkrét típusneveket is megadhat statikusan feloldott típusparaméter-aláírásokban. A nyelv korábbi verzióiban a típusnevet a fordító tudta kikövetkeztetni, de az aláírásban nem sikerült megadni. Az F# 4.1-es verziójában konkrét típusneveket is megadhat statikusan feloldott típusparaméter-aláírásokban. Íme egy példa (vegye figyelembe, hogy ebben a példában továbbra is használni kell, ^ mert a használat ' egyszerűsítése nem támogatott):
let inline konst x _ = x
type CFunctor() =
static member inline fmap (f: ^a -> ^b, a: ^a list) = List.map f a
static member inline fmap (f: ^a -> ^b, a: ^a option) =
match a with
| None -> None
| Some x -> Some (f x)
// default implementation of replace
static member inline replace< ^a, ^b, ^c, ^d, ^e when ^a :> CFunctor and (^a or ^d): (static member fmap: (^b -> ^c) * ^d -> ^e) > (a, f) =
((^a or ^d) : (static member fmap : (^b -> ^c) * ^d -> ^e) (konst a, f))
// call overridden replace if present
static member inline replace< ^a, ^b, ^c when ^b: (static member replace: ^a * ^b -> ^c)>(a: ^a, f: ^b) =
(^b : (static member replace: ^a * ^b -> ^c) (a, f))
let inline replace_instance< ^a, ^b, ^c, ^d when (^a or ^c): (static member replace: ^b * ^c -> ^d)> (a: ^b, f: ^c) =
((^a or ^c): (static member replace: ^b * ^c -> ^d) (a, f))
// Note the concrete type 'CFunctor' specified in the signature
let inline replace (a: ^a) (f: ^b): ^a0 when (CFunctor or ^b): (static member replace: ^a * ^b -> ^a0) =
replace_instance<CFunctor, _, _, _> (a, f)